diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..182a3746 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,50 @@ +name: leapjs - Build Library and Run Unit Tests + +on: [push, pull_request] + +jobs: + build: + name: Build Library and Run Unit Tests + runs-on: ubuntu-latest + steps: + + # Checkout + - name: Checkout repository + uses: actions/checkout@v2 + + # Install Node + - name: Use Node.js + uses: actions/setup-node@v1 + with: + node-version: '12.x' + + # Install Dependencies + - name: Install NPM Dependencies + run: npm ci + + # Build and Run Tests + - name: Build Library and Run Tests + run: ./node_modules/.bin/grunt test + + # Commit All Build Artifacts + - name: Commit Build Artifacts + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + set +e + git add * + git diff-index --quiet HEAD || git commit -m "Build Leap.js" + + # Push Build Artifacts + - name: Push Changes to branch + id: push-build + uses: ad-m/github-push-action@master + continue-on-error: true + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.ref }} + + # Reenable Errors + - name: Clean Up + if: steps.push-build.outcome == 'success' && steps.push-build.conclusion == 'success' + run: set -e diff --git a/Gruntfile.js b/Gruntfile.js index 34f15aa6..38717bbd 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -4,7 +4,7 @@ module.exports = function(grunt){ \n * LeapJS v<%= pkg.version %> \ \n * http://github.com/leapmotion/leapjs/ \ \n * \ -\n * Copyright 2013 LeapMotion, Inc. and other contributors \ +\n * Copyright 2020 Ultraleap, Inc. and other contributors \ \n * Released under the Apache-2.0 license \ \n * http://github.com/leapmotion/leapjs/blob/master/LICENSE \ \n */"; @@ -95,9 +95,9 @@ module.exports = function(grunt){ }, exec: { - 'test-browser': './node_modules/.bin/mocha-chrome -R dot test/helpers/browser.html', + 'test-browser': '"./node_modules/.bin/mocha-headless-chrome" -r dot -f test/helpers/browser.html', // -i -g stands for inverse grep. Tests tagged browser-only will be excluded. - 'test-node': './node_modules/.bin/mocha lib/index.js test/helpers/node.js test/*.js -R dot -i -g browser-only', + 'test-node': '"./node_modules/.bin/mocha" lib/index.js test/helpers/node.js test/*.js -R dot -i -g browser-only', 'test-integration': 'node integration_test/reconnection.js && node integration_test/protocol_versions.js' } }); diff --git a/Makefile b/Makefile index 7833125a..99396bc2 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ test: build test-only test-only: test-node test-browser test-integration test-browser: - ./node_modules/.bin/mocha-chrome -R dot test/helpers/browser.html + "./node_modules/.bin/mocha-headless-chrome" -r dot -f test/helpers/browser.html test-node: ./node_modules/.bin/mocha lib/index.js test/helpers/node.js test/*.js -R dot diff --git a/bower.json b/bower.json index 11a3a0a0..05c92f15 100644 --- a/bower.json +++ b/bower.json @@ -1,9 +1,9 @@ { "name": "leapjs", - "version": "1.0.0", + "version": "1.1.0", "homepage": "https://github.com/leapmotion/leapjs", "description": "JavaScript client for the Leap Motion Controller", - "main": "leap-1.0.0.js", + "main": "leap-1.1.0.js", "keywords": [ "leap", "leapmotion", diff --git a/examples/css-visualizer.html b/examples/css-visualizer.html index d635a156..c9ee4fbb 100644 --- a/examples/css-visualizer.html +++ b/examples/css-visualizer.html @@ -1,7 +1,7 @@ DOM Visualizer - Leap - + + + - - - - - - - - -
-
-
-
-
-

-
-
-
-
-

-
-
-
-
-

-
-
-
-
-

-
-
-
-
-

-
- - \ No newline at end of file diff --git a/examples/iframe.html b/examples/iframe.html index a576c40a..9308be4f 100644 --- a/examples/iframe.html +++ b/examples/iframe.html @@ -1,7 +1,7 @@ iFrame - Leap - + diff --git a/examples/lib/leap-plugins-0.1.6.js b/examples/lib/leap-plugins-0.1.6.js index d59c7364..ea636fb9 100644 --- a/examples/lib/leap-plugins-0.1.6.js +++ b/examples/lib/leap-plugins-0.1.6.js @@ -900,7 +900,7 @@ function Recording (options){ 'id', 'timestamp', // this should be replace/upgraded with a whitelist instead of a blacklist. - // leaving out r,s,y, and gestures + // leaving out r,s,y {hands: [[ 'id', 'type', @@ -1699,7 +1699,6 @@ Recording.prototype = { finalFrame.hands = []; finalFrame.fingers = []; finalFrame.pointables = []; - finalFrame.tools = []; this.sendImmediateFrame(finalFrame); }, diff --git a/examples/lib/three.js b/examples/lib/three.js index 37bf01f1..2604749d 100644 --- a/examples/lib/three.js +++ b/examples/lib/three.js @@ -1,38491 +1,37287 @@ -/** - * @author mrdoob / http://mrdoob.com/ - * @author Larry Battle / http://bateru.com/news - * @author bhouston / http://exocortex.com - */ - -var THREE = { REVISION: '67' }; +// threejs.org/license +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.THREE = {})); +}(this, (function (exports) { 'use strict'; + + // Polyfills + if (Number.EPSILON === undefined) { + Number.EPSILON = Math.pow(2, -52); + } + + if (Number.isInteger === undefined) { + // Missing in IE + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger + Number.isInteger = function (value) { + return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; + }; + } // -self.console = self.console || { - info: function () {}, - log: function () {}, - debug: function () {}, - warn: function () {}, - error: function () {} + if (Math.sign === undefined) { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign + Math.sign = function (x) { + return x < 0 ? -1 : x > 0 ? 1 : +x; + }; + } -}; + if ('name' in Function.prototype === false) { + // Missing in IE + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name + Object.defineProperty(Function.prototype, 'name', { + get: function get() { + return this.toString().match(/^\s*function\s*([^\(\s]*)/)[1]; + } + }); + } -// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ -// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating + if (Object.assign === undefined) { + // Missing in IE + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + Object.assign = function (target) { -// requestAnimationFrame polyfill by Erik Möller -// fixes from Paul Irish and Tino Zijdel -// using 'self' instead of 'window' for compatibility with both NodeJS and IE10. -( function () { + if (target === undefined || target === null) { + throw new TypeError('Cannot convert undefined or null to object'); + } - var lastTime = 0; - var vendors = [ 'ms', 'moz', 'webkit', 'o' ]; + var output = Object(target); - for ( var x = 0; x < vendors.length && !self.requestAnimationFrame; ++ x ) { + for (var index = 1; index < arguments.length; index++) { + var source = arguments[index]; - self.requestAnimationFrame = self[ vendors[ x ] + 'RequestAnimationFrame' ]; - self.cancelAnimationFrame = self[ vendors[ x ] + 'CancelAnimationFrame' ] || self[ vendors[ x ] + 'CancelRequestAnimationFrame' ]; + if (source !== undefined && source !== null) { + for (var nextKey in source) { + if (Object.prototype.hasOwnProperty.call(source, nextKey)) { + output[nextKey] = source[nextKey]; + } + } + } + } + return output; + }; } - if ( self.requestAnimationFrame === undefined && self['setTimeout'] !== undefined ) { + var REVISION = '122'; + var MOUSE = { + LEFT: 0, + MIDDLE: 1, + RIGHT: 2, + ROTATE: 0, + DOLLY: 1, + PAN: 2 + }; + var TOUCH = { + ROTATE: 0, + PAN: 1, + DOLLY_PAN: 2, + DOLLY_ROTATE: 3 + }; + var CullFaceNone = 0; + var CullFaceBack = 1; + var CullFaceFront = 2; + var CullFaceFrontBack = 3; + var BasicShadowMap = 0; + var PCFShadowMap = 1; + var PCFSoftShadowMap = 2; + var VSMShadowMap = 3; + var FrontSide = 0; + var BackSide = 1; + var DoubleSide = 2; + var FlatShading = 1; + var SmoothShading = 2; + var NoBlending = 0; + var NormalBlending = 1; + var AdditiveBlending = 2; + var SubtractiveBlending = 3; + var MultiplyBlending = 4; + var CustomBlending = 5; + var AddEquation = 100; + var SubtractEquation = 101; + var ReverseSubtractEquation = 102; + var MinEquation = 103; + var MaxEquation = 104; + var ZeroFactor = 200; + var OneFactor = 201; + var SrcColorFactor = 202; + var OneMinusSrcColorFactor = 203; + var SrcAlphaFactor = 204; + var OneMinusSrcAlphaFactor = 205; + var DstAlphaFactor = 206; + var OneMinusDstAlphaFactor = 207; + var DstColorFactor = 208; + var OneMinusDstColorFactor = 209; + var SrcAlphaSaturateFactor = 210; + var NeverDepth = 0; + var AlwaysDepth = 1; + var LessDepth = 2; + var LessEqualDepth = 3; + var EqualDepth = 4; + var GreaterEqualDepth = 5; + var GreaterDepth = 6; + var NotEqualDepth = 7; + var MultiplyOperation = 0; + var MixOperation = 1; + var AddOperation = 2; + var NoToneMapping = 0; + var LinearToneMapping = 1; + var ReinhardToneMapping = 2; + var CineonToneMapping = 3; + var ACESFilmicToneMapping = 4; + var CustomToneMapping = 5; + var UVMapping = 300; + var CubeReflectionMapping = 301; + var CubeRefractionMapping = 302; + var EquirectangularReflectionMapping = 303; + var EquirectangularRefractionMapping = 304; + var CubeUVReflectionMapping = 306; + var CubeUVRefractionMapping = 307; + var RepeatWrapping = 1000; + var ClampToEdgeWrapping = 1001; + var MirroredRepeatWrapping = 1002; + var NearestFilter = 1003; + var NearestMipmapNearestFilter = 1004; + var NearestMipMapNearestFilter = 1004; + var NearestMipmapLinearFilter = 1005; + var NearestMipMapLinearFilter = 1005; + var LinearFilter = 1006; + var LinearMipmapNearestFilter = 1007; + var LinearMipMapNearestFilter = 1007; + var LinearMipmapLinearFilter = 1008; + var LinearMipMapLinearFilter = 1008; + var UnsignedByteType = 1009; + var ByteType = 1010; + var ShortType = 1011; + var UnsignedShortType = 1012; + var IntType = 1013; + var UnsignedIntType = 1014; + var FloatType = 1015; + var HalfFloatType = 1016; + var UnsignedShort4444Type = 1017; + var UnsignedShort5551Type = 1018; + var UnsignedShort565Type = 1019; + var UnsignedInt248Type = 1020; + var AlphaFormat = 1021; + var RGBFormat = 1022; + var RGBAFormat = 1023; + var LuminanceFormat = 1024; + var LuminanceAlphaFormat = 1025; + var RGBEFormat = RGBAFormat; + var DepthFormat = 1026; + var DepthStencilFormat = 1027; + var RedFormat = 1028; + var RedIntegerFormat = 1029; + var RGFormat = 1030; + var RGIntegerFormat = 1031; + var RGBIntegerFormat = 1032; + var RGBAIntegerFormat = 1033; + var RGB_S3TC_DXT1_Format = 33776; + var RGBA_S3TC_DXT1_Format = 33777; + var RGBA_S3TC_DXT3_Format = 33778; + var RGBA_S3TC_DXT5_Format = 33779; + var RGB_PVRTC_4BPPV1_Format = 35840; + var RGB_PVRTC_2BPPV1_Format = 35841; + var RGBA_PVRTC_4BPPV1_Format = 35842; + var RGBA_PVRTC_2BPPV1_Format = 35843; + var RGB_ETC1_Format = 36196; + var RGB_ETC2_Format = 37492; + var RGBA_ETC2_EAC_Format = 37496; + var RGBA_ASTC_4x4_Format = 37808; + var RGBA_ASTC_5x4_Format = 37809; + var RGBA_ASTC_5x5_Format = 37810; + var RGBA_ASTC_6x5_Format = 37811; + var RGBA_ASTC_6x6_Format = 37812; + var RGBA_ASTC_8x5_Format = 37813; + var RGBA_ASTC_8x6_Format = 37814; + var RGBA_ASTC_8x8_Format = 37815; + var RGBA_ASTC_10x5_Format = 37816; + var RGBA_ASTC_10x6_Format = 37817; + var RGBA_ASTC_10x8_Format = 37818; + var RGBA_ASTC_10x10_Format = 37819; + var RGBA_ASTC_12x10_Format = 37820; + var RGBA_ASTC_12x12_Format = 37821; + var RGBA_BPTC_Format = 36492; + var SRGB8_ALPHA8_ASTC_4x4_Format = 37840; + var SRGB8_ALPHA8_ASTC_5x4_Format = 37841; + var SRGB8_ALPHA8_ASTC_5x5_Format = 37842; + var SRGB8_ALPHA8_ASTC_6x5_Format = 37843; + var SRGB8_ALPHA8_ASTC_6x6_Format = 37844; + var SRGB8_ALPHA8_ASTC_8x5_Format = 37845; + var SRGB8_ALPHA8_ASTC_8x6_Format = 37846; + var SRGB8_ALPHA8_ASTC_8x8_Format = 37847; + var SRGB8_ALPHA8_ASTC_10x5_Format = 37848; + var SRGB8_ALPHA8_ASTC_10x6_Format = 37849; + var SRGB8_ALPHA8_ASTC_10x8_Format = 37850; + var SRGB8_ALPHA8_ASTC_10x10_Format = 37851; + var SRGB8_ALPHA8_ASTC_12x10_Format = 37852; + var SRGB8_ALPHA8_ASTC_12x12_Format = 37853; + var LoopOnce = 2200; + var LoopRepeat = 2201; + var LoopPingPong = 2202; + var InterpolateDiscrete = 2300; + var InterpolateLinear = 2301; + var InterpolateSmooth = 2302; + var ZeroCurvatureEnding = 2400; + var ZeroSlopeEnding = 2401; + var WrapAroundEnding = 2402; + var NormalAnimationBlendMode = 2500; + var AdditiveAnimationBlendMode = 2501; + var TrianglesDrawMode = 0; + var TriangleStripDrawMode = 1; + var TriangleFanDrawMode = 2; + var LinearEncoding = 3000; + var sRGBEncoding = 3001; + var GammaEncoding = 3007; + var RGBEEncoding = 3002; + var LogLuvEncoding = 3003; + var RGBM7Encoding = 3004; + var RGBM16Encoding = 3005; + var RGBDEncoding = 3006; + var BasicDepthPacking = 3200; + var RGBADepthPacking = 3201; + var TangentSpaceNormalMap = 0; + var ObjectSpaceNormalMap = 1; + var ZeroStencilOp = 0; + var KeepStencilOp = 7680; + var ReplaceStencilOp = 7681; + var IncrementStencilOp = 7682; + var DecrementStencilOp = 7683; + var IncrementWrapStencilOp = 34055; + var DecrementWrapStencilOp = 34056; + var InvertStencilOp = 5386; + var NeverStencilFunc = 512; + var LessStencilFunc = 513; + var EqualStencilFunc = 514; + var LessEqualStencilFunc = 515; + var GreaterStencilFunc = 516; + var NotEqualStencilFunc = 517; + var GreaterEqualStencilFunc = 518; + var AlwaysStencilFunc = 519; + var StaticDrawUsage = 35044; + var DynamicDrawUsage = 35048; + var StreamDrawUsage = 35040; + var StaticReadUsage = 35045; + var DynamicReadUsage = 35049; + var StreamReadUsage = 35041; + var StaticCopyUsage = 35046; + var DynamicCopyUsage = 35050; + var StreamCopyUsage = 35042; + var GLSL1 = "100"; + var GLSL3 = "300 es"; + + /** + * https://github.com/mrdoob/eventdispatcher.js/ + */ + function EventDispatcher() {} - self.requestAnimationFrame = function ( callback ) { + Object.assign(EventDispatcher.prototype, { + addEventListener: function addEventListener(type, listener) { + if (this._listeners === undefined) this._listeners = {}; + var listeners = this._listeners; - var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) ); - var id = self.setTimeout( function() { callback( currTime + timeToCall ); }, timeToCall ); - lastTime = currTime + timeToCall; - return id; + if (listeners[type] === undefined) { + listeners[type] = []; + } - }; + if (listeners[type].indexOf(listener) === -1) { + listeners[type].push(listener); + } + }, + hasEventListener: function hasEventListener(type, listener) { + if (this._listeners === undefined) return false; + var listeners = this._listeners; + return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1; + }, + removeEventListener: function removeEventListener(type, listener) { + if (this._listeners === undefined) return; + var listeners = this._listeners; + var listenerArray = listeners[type]; - } + if (listenerArray !== undefined) { + var index = listenerArray.indexOf(listener); - if( self.cancelAnimationFrame === undefined && self['clearTimeout'] !== undefined ) { + if (index !== -1) { + listenerArray.splice(index, 1); + } + } + }, + dispatchEvent: function dispatchEvent(event) { + if (this._listeners === undefined) return; + var listeners = this._listeners; + var listenerArray = listeners[event.type]; - self.cancelAnimationFrame = function ( id ) { self.clearTimeout( id ) }; + if (listenerArray !== undefined) { + event.target = this; // Make a copy, in case listeners are removed while iterating. - } + var array = listenerArray.slice(0); -}() ); + for (var i = 0, l = array.length; i < l; i++) { + array[i].call(this, event); + } + } + } + }); -// GL STATE CONSTANTS + var _lut = []; -THREE.CullFaceNone = 0; -THREE.CullFaceBack = 1; -THREE.CullFaceFront = 2; -THREE.CullFaceFrontBack = 3; + for (var i = 0; i < 256; i++) { + _lut[i] = (i < 16 ? '0' : '') + i.toString(16); + } -THREE.FrontFaceDirectionCW = 0; -THREE.FrontFaceDirectionCCW = 1; + var _seed = 1234567; + var MathUtils = { + DEG2RAD: Math.PI / 180, + RAD2DEG: 180 / Math.PI, + generateUUID: function generateUUID() { + // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 + var d0 = Math.random() * 0xffffffff | 0; + var d1 = Math.random() * 0xffffffff | 0; + var d2 = Math.random() * 0xffffffff | 0; + var d3 = Math.random() * 0xffffffff | 0; + var 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. -// SHADOWING TYPES + return uuid.toUpperCase(); + }, + clamp: 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 + euclideanModulo: function euclideanModulo(n, m) { + return (n % m + m) % m; + }, + // Linear mapping from range to range + mapLinear: function mapLinear(x, a1, a2, b1, b2) { + return b1 + (x - a1) * (b2 - b1) / (a2 - a1); + }, + // https://en.wikipedia.org/wiki/Linear_interpolation + lerp: function lerp(x, y, t) { + return (1 - t) * x + t * y; + }, + // http://en.wikipedia.org/wiki/Smoothstep + 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); + }, + smootherstep: 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 + randInt: function randInt(low, high) { + return low + Math.floor(Math.random() * (high - low + 1)); + }, + // Random float from interval + randFloat: function randFloat(low, high) { + return low + Math.random() * (high - low); + }, + // Random float from <-range/2, range/2> interval + randFloatSpread: function randFloatSpread(range) { + return range * (0.5 - Math.random()); + }, + // Deterministic pseudo-random float in the interval [ 0, 1 ] + seededRandom: function seededRandom(s) { + if (s !== undefined) _seed = s % 2147483647; // Park-Miller algorithm -THREE.BasicShadowMap = 0; -THREE.PCFShadowMap = 1; -THREE.PCFSoftShadowMap = 2; + _seed = _seed * 16807 % 2147483647; + return (_seed - 1) / 2147483646; + }, + degToRad: function degToRad(degrees) { + return degrees * MathUtils.DEG2RAD; + }, + radToDeg: function radToDeg(radians) { + return radians * MathUtils.RAD2DEG; + }, + isPowerOfTwo: function isPowerOfTwo(value) { + return (value & value - 1) === 0 && value !== 0; + }, + ceilPowerOfTwo: function ceilPowerOfTwo(value) { + return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2)); + }, + floorPowerOfTwo: function floorPowerOfTwo(value) { + return Math.pow(2, Math.floor(Math.log(value) / Math.LN2)); + }, + setQuaternionFromProperEuler: 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 + var cos = Math.cos; + var sin = Math.sin; + var c2 = cos(b / 2); + var s2 = sin(b / 2); + var c13 = cos((a + c) / 2); + var s13 = sin((a + c) / 2); + var c1_3 = cos((a - c) / 2); + var s1_3 = sin((a - c) / 2); + var c3_1 = cos((c - a) / 2); + var s3_1 = sin((c - a) / 2); + + switch (order) { + case 'XYX': + q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13); + break; -// MATERIAL CONSTANTS + case 'YZY': + q.set(s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13); + break; -// side + case 'ZXZ': + q.set(s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13); + break; -THREE.FrontSide = 0; -THREE.BackSide = 1; -THREE.DoubleSide = 2; + case 'XZX': + q.set(c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13); + break; -// shading + case 'YXY': + q.set(s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13); + break; -THREE.NoShading = 0; -THREE.FlatShading = 1; -THREE.SmoothShading = 2; + case 'ZYZ': + q.set(s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13); + break; -// colors + default: + console.warn('THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order); + } + } + }; -THREE.NoColors = 0; -THREE.FaceColors = 1; -THREE.VertexColors = 2; + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } -// blending modes + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } -THREE.NoBlending = 0; -THREE.NormalBlending = 1; -THREE.AdditiveBlending = 2; -THREE.SubtractiveBlending = 3; -THREE.MultiplyBlending = 4; -THREE.CustomBlending = 5; + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; + } -// custom blending equations -// (numbers start from 100 not to clash with other -// mappings to OpenGL constants defined in Texture.js) + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } -THREE.AddEquation = 100; -THREE.SubtractEquation = 101; -THREE.ReverseSubtractEquation = 102; + return self; + } -// custom blending destination factors + var Vector2 = /*#__PURE__*/function () { + function Vector2(x, y) { + if (x === void 0) { + x = 0; + } -THREE.ZeroFactor = 200; -THREE.OneFactor = 201; -THREE.SrcColorFactor = 202; -THREE.OneMinusSrcColorFactor = 203; -THREE.SrcAlphaFactor = 204; -THREE.OneMinusSrcAlphaFactor = 205; -THREE.DstAlphaFactor = 206; -THREE.OneMinusDstAlphaFactor = 207; + if (y === void 0) { + y = 0; + } -// custom blending source factors + Object.defineProperty(this, 'isVector2', { + value: true + }); + this.x = x; + this.y = y; + } -//THREE.ZeroFactor = 200; -//THREE.OneFactor = 201; -//THREE.SrcAlphaFactor = 204; -//THREE.OneMinusSrcAlphaFactor = 205; -//THREE.DstAlphaFactor = 206; -//THREE.OneMinusDstAlphaFactor = 207; -THREE.DstColorFactor = 208; -THREE.OneMinusDstColorFactor = 209; -THREE.SrcAlphaSaturateFactor = 210; + var _proto = Vector2.prototype; + _proto.set = function set(x, y) { + this.x = x; + this.y = y; + return this; + }; -// TEXTURE CONSTANTS + _proto.setScalar = function setScalar(scalar) { + this.x = scalar; + this.y = scalar; + return this; + }; -THREE.MultiplyOperation = 0; -THREE.MixOperation = 1; -THREE.AddOperation = 2; + _proto.setX = function setX(x) { + this.x = x; + return this; + }; -// Mapping modes + _proto.setY = function setY(y) { + this.y = y; + return this; + }; -THREE.UVMapping = function () {}; + _proto.setComponent = function setComponent(index, value) { + switch (index) { + case 0: + this.x = value; + break; -THREE.CubeReflectionMapping = function () {}; -THREE.CubeRefractionMapping = function () {}; + case 1: + this.y = value; + break; -THREE.SphericalReflectionMapping = function () {}; -THREE.SphericalRefractionMapping = function () {}; + default: + throw new Error('index is out of range: ' + index); + } -// Wrapping modes + return this; + }; -THREE.RepeatWrapping = 1000; -THREE.ClampToEdgeWrapping = 1001; -THREE.MirroredRepeatWrapping = 1002; + _proto.getComponent = function getComponent(index) { + switch (index) { + case 0: + return this.x; -// Filters + case 1: + return this.y; -THREE.NearestFilter = 1003; -THREE.NearestMipMapNearestFilter = 1004; -THREE.NearestMipMapLinearFilter = 1005; -THREE.LinearFilter = 1006; -THREE.LinearMipMapNearestFilter = 1007; -THREE.LinearMipMapLinearFilter = 1008; + default: + throw new Error('index is out of range: ' + index); + } + }; -// Data types + _proto.clone = function clone() { + return new this.constructor(this.x, this.y); + }; -THREE.UnsignedByteType = 1009; -THREE.ByteType = 1010; -THREE.ShortType = 1011; -THREE.UnsignedShortType = 1012; -THREE.IntType = 1013; -THREE.UnsignedIntType = 1014; -THREE.FloatType = 1015; + _proto.copy = function copy(v) { + this.x = v.x; + this.y = v.y; + return this; + }; -// Pixel types + _proto.add = function add(v, w) { + if (w !== undefined) { + console.warn('THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.'); + return this.addVectors(v, w); + } -//THREE.UnsignedByteType = 1009; -THREE.UnsignedShort4444Type = 1016; -THREE.UnsignedShort5551Type = 1017; -THREE.UnsignedShort565Type = 1018; + this.x += v.x; + this.y += v.y; + return this; + }; -// Pixel formats + _proto.addScalar = function addScalar(s) { + this.x += s; + this.y += s; + return this; + }; -THREE.AlphaFormat = 1019; -THREE.RGBFormat = 1020; -THREE.RGBAFormat = 1021; -THREE.LuminanceFormat = 1022; -THREE.LuminanceAlphaFormat = 1023; + _proto.addVectors = function addVectors(a, b) { + this.x = a.x + b.x; + this.y = a.y + b.y; + return this; + }; -// Compressed texture formats + _proto.addScaledVector = function addScaledVector(v, s) { + this.x += v.x * s; + this.y += v.y * s; + return this; + }; -THREE.RGB_S3TC_DXT1_Format = 2001; -THREE.RGBA_S3TC_DXT1_Format = 2002; -THREE.RGBA_S3TC_DXT3_Format = 2003; -THREE.RGBA_S3TC_DXT5_Format = 2004; + _proto.sub = function sub(v, w) { + if (w !== undefined) { + console.warn('THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.'); + return this.subVectors(v, w); + } -/* -// Potential future PVRTC compressed texture formats -THREE.RGB_PVRTC_4BPPV1_Format = 2100; -THREE.RGB_PVRTC_2BPPV1_Format = 2101; -THREE.RGBA_PVRTC_4BPPV1_Format = 2102; -THREE.RGBA_PVRTC_2BPPV1_Format = 2103; -*/ + this.x -= v.x; + this.y -= v.y; + return this; + }; -/** - * @author mrdoob / http://mrdoob.com/ - */ + _proto.subScalar = function subScalar(s) { + this.x -= s; + this.y -= s; + return this; + }; -THREE.Color = function ( color ) { + _proto.subVectors = function subVectors(a, b) { + this.x = a.x - b.x; + this.y = a.y - b.y; + return this; + }; - if ( arguments.length === 3 ) { + _proto.multiply = function multiply(v) { + this.x *= v.x; + this.y *= v.y; + return this; + }; - return this.setRGB( arguments[ 0 ], arguments[ 1 ], arguments[ 2 ] ); + _proto.multiplyScalar = function multiplyScalar(scalar) { + this.x *= scalar; + this.y *= scalar; + return this; + }; - } + _proto.divide = function divide(v) { + this.x /= v.x; + this.y /= v.y; + return this; + }; - return this.set( color ) + _proto.divideScalar = function divideScalar(scalar) { + return this.multiplyScalar(1 / scalar); + }; -}; + _proto.applyMatrix3 = function applyMatrix3(m) { + var x = this.x, + y = this.y; + var e = m.elements; + this.x = e[0] * x + e[3] * y + e[6]; + this.y = e[1] * x + e[4] * y + e[7]; + return this; + }; -THREE.Color.prototype = { + _proto.min = function min(v) { + this.x = Math.min(this.x, v.x); + this.y = Math.min(this.y, v.y); + return this; + }; - constructor: THREE.Color, + _proto.max = function max(v) { + this.x = Math.max(this.x, v.x); + this.y = Math.max(this.y, v.y); + return this; + }; - r: 1, g: 1, b: 1, + _proto.clamp = function 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)); + return this; + }; - set: function ( value ) { + _proto.clampScalar = function clampScalar(minVal, maxVal) { + this.x = Math.max(minVal, Math.min(maxVal, this.x)); + this.y = Math.max(minVal, Math.min(maxVal, this.y)); + return this; + }; - if ( value instanceof THREE.Color ) { + _proto.clampLength = function clampLength(min, max) { + var length = this.length(); + return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); + }; - this.copy( value ); + _proto.floor = function floor() { + this.x = Math.floor(this.x); + this.y = Math.floor(this.y); + return this; + }; - } else if ( typeof value === 'number' ) { + _proto.ceil = function ceil() { + this.x = Math.ceil(this.x); + this.y = Math.ceil(this.y); + return this; + }; - this.setHex( value ); + _proto.round = function round() { + this.x = Math.round(this.x); + this.y = Math.round(this.y); + return this; + }; - } else if ( typeof value === 'string' ) { + _proto.roundToZero = function 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); + return this; + }; - this.setStyle( value ); + _proto.negate = function negate() { + this.x = -this.x; + this.y = -this.y; + return this; + }; - } + _proto.dot = function dot(v) { + return this.x * v.x + this.y * v.y; + }; - return this; + _proto.cross = function cross(v) { + return this.x * v.y - this.y * v.x; + }; - }, + _proto.lengthSq = function lengthSq() { + return this.x * this.x + this.y * this.y; + }; - setHex: function ( hex ) { + _proto.length = function length() { + return Math.sqrt(this.x * this.x + this.y * this.y); + }; - hex = Math.floor( hex ); + _proto.manhattanLength = function manhattanLength() { + return Math.abs(this.x) + Math.abs(this.y); + }; - this.r = ( hex >> 16 & 255 ) / 255; - this.g = ( hex >> 8 & 255 ) / 255; - this.b = ( hex & 255 ) / 255; + _proto.normalize = function normalize() { + return this.divideScalar(this.length() || 1); + }; - return this; + _proto.angle = function angle() { + // computes the angle in radians with respect to the positive x-axis + var angle = Math.atan2(-this.y, -this.x) + Math.PI; + return angle; + }; - }, + _proto.distanceTo = function distanceTo(v) { + return Math.sqrt(this.distanceToSquared(v)); + }; - setRGB: function ( r, g, b ) { + _proto.distanceToSquared = function distanceToSquared(v) { + var dx = this.x - v.x, + dy = this.y - v.y; + return dx * dx + dy * dy; + }; - this.r = r; - this.g = g; - this.b = b; + _proto.manhattanDistanceTo = function manhattanDistanceTo(v) { + return Math.abs(this.x - v.x) + Math.abs(this.y - v.y); + }; - return this; + _proto.setLength = function setLength(length) { + return this.normalize().multiplyScalar(length); + }; - }, + _proto.lerp = function lerp(v, alpha) { + this.x += (v.x - this.x) * alpha; + this.y += (v.y - this.y) * alpha; + return this; + }; - setHSL: function ( h, s, l ) { + _proto.lerpVectors = function lerpVectors(v1, v2, alpha) { + this.x = v1.x + (v2.x - v1.x) * alpha; + this.y = v1.y + (v2.y - v1.y) * alpha; + return this; + }; - // h,s,l ranges are in 0.0 - 1.0 + _proto.equals = function equals(v) { + return v.x === this.x && v.y === this.y; + }; - if ( s === 0 ) { + _proto.fromArray = function fromArray(array, offset) { + if (offset === void 0) { + offset = 0; + } - this.r = this.g = this.b = l; + this.x = array[offset]; + this.y = array[offset + 1]; + return this; + }; - } else { + _proto.toArray = function toArray(array, offset) { + if (array === void 0) { + array = []; + } - var hue2rgb = function ( p, q, t ) { + if (offset === void 0) { + offset = 0; + } - if ( t < 0 ) t += 1; - if ( t > 1 ) t -= 1; - if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; - if ( t < 1 / 2 ) return q; - if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); - return p; + array[offset] = this.x; + array[offset + 1] = this.y; + return array; + }; - }; + _proto.fromBufferAttribute = function fromBufferAttribute(attribute, index, offset) { + if (offset !== undefined) { + console.warn('THREE.Vector2: offset has been removed from .fromBufferAttribute().'); + } - var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); - var q = ( 2 * l ) - p; + this.x = attribute.getX(index); + this.y = attribute.getY(index); + return this; + }; - this.r = hue2rgb( q, p, h + 1 / 3 ); - this.g = hue2rgb( q, p, h ); - this.b = hue2rgb( q, p, h - 1 / 3 ); + _proto.rotateAround = function rotateAround(center, angle) { + var c = Math.cos(angle), + s = Math.sin(angle); + var x = this.x - center.x; + var y = this.y - center.y; + this.x = x * c - y * s + center.x; + this.y = x * s + y * c + center.y; + return this; + }; - } + _proto.random = function random() { + this.x = Math.random(); + this.y = Math.random(); + return this; + }; - return this; + _createClass(Vector2, [{ + key: "width", + get: function get() { + return this.x; + }, + set: function set(value) { + this.x = value; + } + }, { + key: "height", + get: function get() { + return this.y; + }, + set: function set(value) { + this.y = value; + } + }]); + + return Vector2; + }(); - }, + var Matrix3 = /*#__PURE__*/function () { + function Matrix3() { + Object.defineProperty(this, 'isMatrix3', { + value: true + }); + this.elements = [1, 0, 0, 0, 1, 0, 0, 0, 1]; - setStyle: function ( style ) { + if (arguments.length > 0) { + console.error('THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.'); + } + } - // rgb(255,0,0) + var _proto = Matrix3.prototype; - if ( /^rgb\((\d+), ?(\d+), ?(\d+)\)$/i.test( style ) ) { + _proto.set = function set(n11, n12, n13, n21, n22, n23, n31, n32, n33) { + var 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; + }; - var color = /^rgb\((\d+), ?(\d+), ?(\d+)\)$/i.exec( style ); + _proto.identity = function identity() { + this.set(1, 0, 0, 0, 1, 0, 0, 0, 1); + return this; + }; - this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255; - this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255; - this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255; + _proto.clone = function clone() { + return new this.constructor().fromArray(this.elements); + }; + _proto.copy = function copy(m) { + var te = this.elements; + var 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; + }; - } - - // rgb(100%,0%,0%) + _proto.extractBasis = function extractBasis(xAxis, yAxis, zAxis) { + xAxis.setFromMatrix3Column(this, 0); + yAxis.setFromMatrix3Column(this, 1); + zAxis.setFromMatrix3Column(this, 2); + return this; + }; - if ( /^rgb\((\d+)\%, ?(\d+)\%, ?(\d+)\%\)$/i.test( style ) ) { + _proto.setFromMatrix4 = function setFromMatrix4(m) { + var 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; + }; - var color = /^rgb\((\d+)\%, ?(\d+)\%, ?(\d+)\%\)$/i.exec( style ); + _proto.multiply = function multiply(m) { + return this.multiplyMatrices(this, m); + }; - this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100; - this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100; - this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100; + _proto.premultiply = function premultiply(m) { + return this.multiplyMatrices(m, this); + }; + _proto.multiplyMatrices = function multiplyMatrices(a, b) { + var ae = a.elements; + var be = b.elements; + var te = this.elements; + var a11 = ae[0], + a12 = ae[3], + a13 = ae[6]; + var a21 = ae[1], + a22 = ae[4], + a23 = ae[7]; + var a31 = ae[2], + a32 = ae[5], + a33 = ae[8]; + var b11 = be[0], + b12 = be[3], + b13 = be[6]; + var b21 = be[1], + b22 = be[4], + b23 = be[7]; + var 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; + }; - } - - // #ff0000 - - if ( /^\#([0-9a-f]{6})$/i.test( style ) ) { + _proto.multiplyScalar = function multiplyScalar(s) { + var 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; + }; - var color = /^\#([0-9a-f]{6})$/i.exec( style ); + _proto.determinant = function determinant() { + var te = this.elements; + var 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; + }; - this.setHex( parseInt( color[ 1 ], 16 ) ); + _proto.getInverse = function getInverse(matrix, throwOnDegenerate) { + if (throwOnDegenerate !== undefined) { + console.warn("THREE.Matrix3: .getInverse() can no longer be configured to throw on degenerate."); + } + + var me = matrix.elements, + te = this.elements, + n11 = me[0], + n21 = me[1], + n31 = me[2], + n12 = me[3], + n22 = me[4], + n32 = me[5], + n13 = me[6], + n23 = me[7], + n33 = me[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); + var 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; + }; + _proto.transpose = function transpose() { + var tmp; + var 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; + }; - } + _proto.getNormalMatrix = function getNormalMatrix(matrix4) { + return this.setFromMatrix4(matrix4).getInverse(this).transpose(); + }; - // #f00 + _proto.transposeIntoArray = function transposeIntoArray(r) { + var 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; + }; - if ( /^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.test( style ) ) { + _proto.setUvTransform = function setUvTransform(tx, ty, sx, sy, rotation, cx, cy) { + var c = Math.cos(rotation); + var 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); + }; - var color = /^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec( style ); + _proto.scale = function scale(sx, sy) { + var te = this.elements; + te[0] *= sx; + te[3] *= sx; + te[6] *= sx; + te[1] *= sy; + te[4] *= sy; + te[7] *= sy; + return this; + }; - this.setHex( parseInt( color[ 1 ] + color[ 1 ] + color[ 2 ] + color[ 2 ] + color[ 3 ] + color[ 3 ], 16 ) ); + _proto.rotate = function rotate(theta) { + var c = Math.cos(theta); + var s = Math.sin(theta); + var te = this.elements; + var a11 = te[0], + a12 = te[3], + a13 = te[6]; + var 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; + }; + _proto.translate = function translate(tx, ty) { + var 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; + }; - } + _proto.equals = function equals(matrix) { + var te = this.elements; + var me = matrix.elements; - // red + for (var i = 0; i < 9; i++) { + if (te[i] !== me[i]) return false; + } + + return true; + }; - if ( /^(\w+)$/i.test( style ) ) { + _proto.fromArray = function fromArray(array, offset) { + if (offset === void 0) { + offset = 0; + } - this.setHex( THREE.ColorKeywords[ style ] ); + for (var i = 0; i < 9; i++) { + this.elements[i] = array[i + offset]; + } return this; + }; - } + _proto.toArray = function toArray(array, offset) { + if (array === void 0) { + array = []; + } + if (offset === void 0) { + offset = 0; + } - }, + var 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; + }; - copy: function ( color ) { + return Matrix3; + }(); - this.r = color.r; - this.g = color.g; - this.b = color.b; + var _canvas; - return this; + var ImageUtils = { + getDataURL: function getDataURL(image) { + if (/^data:/i.test(image.src)) { + return image.src; + } - }, + if (typeof HTMLCanvasElement == 'undefined') { + return image.src; + } - copyGammaToLinear: function ( color ) { + var canvas; - this.r = color.r * color.r; - this.g = color.g * color.g; - this.b = color.b * color.b; + if (image instanceof HTMLCanvasElement) { + canvas = image; + } else { + if (_canvas === undefined) _canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas'); + _canvas.width = image.width; + _canvas.height = image.height; - return this; + var context = _canvas.getContext('2d'); - }, + if (image instanceof ImageData) { + context.putImageData(image, 0, 0); + } else { + context.drawImage(image, 0, 0, image.width, image.height); + } - copyLinearToGamma: function ( color ) { + canvas = _canvas; + } - this.r = Math.sqrt( color.r ); - this.g = Math.sqrt( color.g ); - this.b = Math.sqrt( color.b ); + if (canvas.width > 2048 || canvas.height > 2048) { + return canvas.toDataURL('image/jpeg', 0.6); + } else { + return canvas.toDataURL('image/png'); + } + } + }; - return this; + var textureId = 0; + + function Texture(image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding) { + Object.defineProperty(this, 'id', { + value: textureId++ + }); + this.uuid = MathUtils.generateUUID(); + this.name = ''; + this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE; + this.mipmaps = []; + this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING; + this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping; + this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping; + this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; + this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter; + this.anisotropy = anisotropy !== undefined ? anisotropy : 1; + this.format = format !== undefined ? format : RGBAFormat; + this.internalFormat = null; + this.type = type !== undefined ? type : UnsignedByteType; + this.offset = new Vector2(0, 0); + this.repeat = new Vector2(1, 1); + this.center = new Vector2(0, 0); + this.rotation = 0; + this.matrixAutoUpdate = true; + this.matrix = new Matrix3(); + this.generateMipmaps = true; + this.premultiplyAlpha = false; + this.flipY = true; + this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) + // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. + // + // Also changing the encoding after already used by a Material will not automatically make the Material + // update. You need to explicitly call Material.needsUpdate to trigger it to recompile. - }, + this.encoding = encoding !== undefined ? encoding : LinearEncoding; + this.version = 0; + this.onUpdate = null; + } - convertGammaToLinear: function () { + Texture.DEFAULT_IMAGE = undefined; + Texture.DEFAULT_MAPPING = UVMapping; + Texture.prototype = Object.assign(Object.create(EventDispatcher.prototype), { + constructor: Texture, + isTexture: true, + updateMatrix: function updateMatrix() { + this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y); + }, + clone: function clone() { + return new this.constructor().copy(this); + }, + copy: function copy(source) { + this.name = source.name; + this.image = source.image; + this.mipmaps = source.mipmaps.slice(0); + this.mapping = source.mapping; + this.wrapS = source.wrapS; + this.wrapT = source.wrapT; + this.magFilter = source.magFilter; + this.minFilter = source.minFilter; + this.anisotropy = source.anisotropy; + this.format = source.format; + this.internalFormat = source.internalFormat; + this.type = source.type; + this.offset.copy(source.offset); + this.repeat.copy(source.repeat); + this.center.copy(source.center); + this.rotation = source.rotation; + this.matrixAutoUpdate = source.matrixAutoUpdate; + this.matrix.copy(source.matrix); + this.generateMipmaps = source.generateMipmaps; + this.premultiplyAlpha = source.premultiplyAlpha; + this.flipY = source.flipY; + this.unpackAlignment = source.unpackAlignment; + this.encoding = source.encoding; + return this; + }, + toJSON: function toJSON(meta) { + var isRootObject = meta === undefined || typeof meta === 'string'; + + if (!isRootObject && meta.textures[this.uuid] !== undefined) { + return meta.textures[this.uuid]; + } + + var output = { + metadata: { + version: 4.5, + type: 'Texture', + generator: 'Texture.toJSON' + }, + uuid: this.uuid, + name: this.name, + mapping: this.mapping, + repeat: [this.repeat.x, this.repeat.y], + offset: [this.offset.x, this.offset.y], + center: [this.center.x, this.center.y], + rotation: this.rotation, + wrap: [this.wrapS, this.wrapT], + format: this.format, + type: this.type, + encoding: this.encoding, + minFilter: this.minFilter, + magFilter: this.magFilter, + anisotropy: this.anisotropy, + flipY: this.flipY, + premultiplyAlpha: this.premultiplyAlpha, + unpackAlignment: this.unpackAlignment + }; - var r = this.r, g = this.g, b = this.b; + if (this.image !== undefined) { + // TODO: Move to THREE.Image + var image = this.image; - this.r = r * r; - this.g = g * g; - this.b = b * b; + if (image.uuid === undefined) { + image.uuid = MathUtils.generateUUID(); // UGH + } - return this; + if (!isRootObject && meta.images[image.uuid] === undefined) { + var url; - }, + if (Array.isArray(image)) { + // process array of images e.g. CubeTexture + url = []; - convertLinearToGamma: function () { - - this.r = Math.sqrt( this.r ); - this.g = Math.sqrt( this.g ); - this.b = Math.sqrt( this.b ); + for (var i = 0, l = image.length; i < l; i++) { + url.push(ImageUtils.getDataURL(image[i])); + } + } else { + // process single image + url = ImageUtils.getDataURL(image); + } - return this; + meta.images[image.uuid] = { + uuid: image.uuid, + url: url + }; + } - }, + output.image = image.uuid; + } - getHex: function () { + if (!isRootObject) { + meta.textures[this.uuid] = output; + } - return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0; + return output; + }, + dispose: function dispose() { + this.dispatchEvent({ + type: 'dispose' + }); + }, + transformUv: function transformUv(uv) { + if (this.mapping !== UVMapping) return uv; + uv.applyMatrix3(this.matrix); + + if (uv.x < 0 || uv.x > 1) { + switch (this.wrapS) { + case RepeatWrapping: + uv.x = uv.x - Math.floor(uv.x); + break; - }, + case ClampToEdgeWrapping: + uv.x = uv.x < 0 ? 0 : 1; + break; - getHexString: function () { + case MirroredRepeatWrapping: + if (Math.abs(Math.floor(uv.x) % 2) === 1) { + uv.x = Math.ceil(uv.x) - uv.x; + } else { + uv.x = uv.x - Math.floor(uv.x); + } - return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 ); + break; + } + } - }, + if (uv.y < 0 || uv.y > 1) { + switch (this.wrapT) { + case RepeatWrapping: + uv.y = uv.y - Math.floor(uv.y); + break; - getHSL: function ( optionalTarget ) { + case ClampToEdgeWrapping: + uv.y = uv.y < 0 ? 0 : 1; + break; - // h,s,l ranges are in 0.0 - 1.0 + case MirroredRepeatWrapping: + if (Math.abs(Math.floor(uv.y) % 2) === 1) { + uv.y = Math.ceil(uv.y) - uv.y; + } else { + uv.y = uv.y - Math.floor(uv.y); + } - var hsl = optionalTarget || { h: 0, s: 0, l: 0 }; + break; + } + } - var r = this.r, g = this.g, b = this.b; + if (this.flipY) { + uv.y = 1 - uv.y; + } - var max = Math.max( r, g, b ); - var min = Math.min( r, g, b ); + return uv; + } + }); + Object.defineProperty(Texture.prototype, "needsUpdate", { + set: function set(value) { + if (value === true) this.version++; + } + }); - var hue, saturation; - var lightness = ( min + max ) / 2.0; + var Vector4 = /*#__PURE__*/function () { + function Vector4(x, y, z, w) { + if (x === void 0) { + x = 0; + } - if ( min === max ) { + if (y === void 0) { + y = 0; + } - hue = 0; - saturation = 0; + if (z === void 0) { + z = 0; + } - } else { + if (w === void 0) { + w = 1; + } - var delta = max - min; + Object.defineProperty(this, 'isVector4', { + value: true + }); + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } - saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); + var _proto = Vector4.prototype; - switch ( max ) { + _proto.set = function set(x, y, z, w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + return this; + }; - case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; - case g: hue = ( b - r ) / delta + 2; break; - case b: hue = ( r - g ) / delta + 4; break; + _proto.setScalar = function setScalar(scalar) { + this.x = scalar; + this.y = scalar; + this.z = scalar; + this.w = scalar; + return this; + }; - } + _proto.setX = function setX(x) { + this.x = x; + return this; + }; - hue /= 6; + _proto.setY = function setY(y) { + this.y = y; + return this; + }; - } + _proto.setZ = function setZ(z) { + this.z = z; + return this; + }; - hsl.h = hue; - hsl.s = saturation; - hsl.l = lightness; + _proto.setW = function setW(w) { + this.w = w; + return this; + }; - return hsl; + _proto.setComponent = function setComponent(index, value) { + switch (index) { + case 0: + this.x = value; + break; - }, + case 1: + this.y = value; + break; - getStyle: function () { + case 2: + this.z = value; + break; - return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')'; + case 3: + this.w = value; + break; - }, + default: + throw new Error('index is out of range: ' + index); + } - offsetHSL: function ( h, s, l ) { + return this; + }; - var hsl = this.getHSL(); + _proto.getComponent = function getComponent(index) { + switch (index) { + case 0: + return this.x; - hsl.h += h; hsl.s += s; hsl.l += l; + case 1: + return this.y; - this.setHSL( hsl.h, hsl.s, hsl.l ); + case 2: + return this.z; - return this; + case 3: + return this.w; - }, + default: + throw new Error('index is out of range: ' + index); + } + }; - add: function ( color ) { + _proto.clone = function clone() { + return new this.constructor(this.x, this.y, this.z, this.w); + }; - this.r += color.r; - this.g += color.g; - this.b += color.b; + _proto.copy = function copy(v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + this.w = v.w !== undefined ? v.w : 1; + return this; + }; - return this; + _proto.add = function add(v, w) { + if (w !== undefined) { + console.warn('THREE.Vector4: .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; + this.w += v.w; + return this; + }; - addColors: function ( color1, color2 ) { + _proto.addScalar = function addScalar(s) { + this.x += s; + this.y += s; + this.z += s; + this.w += s; + return this; + }; - this.r = color1.r + color2.r; - this.g = color1.g + color2.g; - this.b = color1.b + color2.b; + _proto.addVectors = function addVectors(a, b) { + this.x = a.x + b.x; + this.y = a.y + b.y; + this.z = a.z + b.z; + this.w = a.w + b.w; + return this; + }; - return this; + _proto.addScaledVector = function addScaledVector(v, s) { + this.x += v.x * s; + this.y += v.y * s; + this.z += v.z * s; + this.w += v.w * s; + return this; + }; - }, + _proto.sub = function sub(v, w) { + if (w !== undefined) { + console.warn('THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.'); + return this.subVectors(v, w); + } - addScalar: function ( s ) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + this.w -= v.w; + return this; + }; - this.r += s; - this.g += s; - this.b += s; + _proto.subScalar = function subScalar(s) { + this.x -= s; + this.y -= s; + this.z -= s; + this.w -= s; + return this; + }; - return this; + _proto.subVectors = function subVectors(a, b) { + this.x = a.x - b.x; + this.y = a.y - b.y; + this.z = a.z - b.z; + this.w = a.w - b.w; + return this; + }; - }, + _proto.multiplyScalar = function multiplyScalar(scalar) { + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + this.w *= scalar; + return this; + }; - multiply: function ( color ) { + _proto.applyMatrix4 = function applyMatrix4(m) { + var x = this.x, + y = this.y, + z = this.z, + w = this.w; + var e = m.elements; + 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; + this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w; + return this; + }; - this.r *= color.r; - this.g *= color.g; - this.b *= color.b; + _proto.divideScalar = function divideScalar(scalar) { + return this.multiplyScalar(1 / scalar); + }; - return this; + _proto.setAxisAngleFromQuaternion = function setAxisAngleFromQuaternion(q) { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm + // q is assumed to be normalized + this.w = 2 * Math.acos(q.w); + var s = Math.sqrt(1 - q.w * q.w); - }, + if (s < 0.0001) { + this.x = 1; + this.y = 0; + this.z = 0; + } else { + this.x = q.x / s; + this.y = q.y / s; + this.z = q.z / s; + } - multiplyScalar: function ( s ) { + return this; + }; - this.r *= s; - this.g *= s; - this.b *= s; + _proto.setAxisAngleFromRotationMatrix = function setAxisAngleFromRotationMatrix(m) { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + var angle, x, y, z; // variables for result - return this; + var epsilon = 0.01, + // margin to allow for rounding errors + epsilon2 = 0.1, + // margin to distinguish between 0 and 180 degrees + 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]; + + if (Math.abs(m12 - m21) < epsilon && Math.abs(m13 - m31) < epsilon && Math.abs(m23 - m32) < epsilon) { + // singularity found + // first check for identity matrix which must have +1 for all terms + // in leading diagonal and zero in other terms + if (Math.abs(m12 + m21) < epsilon2 && Math.abs(m13 + m31) < epsilon2 && Math.abs(m23 + m32) < epsilon2 && Math.abs(m11 + m22 + m33 - 3) < epsilon2) { + // this singularity is identity matrix so angle = 0 + this.set(1, 0, 0, 0); + return this; // zero angle, arbitrary axis + } // otherwise this singularity is angle = 180 + + + angle = Math.PI; + var xx = (m11 + 1) / 2; + var yy = (m22 + 1) / 2; + var zz = (m33 + 1) / 2; + var xy = (m12 + m21) / 4; + var xz = (m13 + m31) / 4; + var yz = (m23 + m32) / 4; + + if (xx > yy && xx > zz) { + // m11 is the largest diagonal term + if (xx < epsilon) { + x = 0; + y = 0.707106781; + z = 0.707106781; + } else { + x = Math.sqrt(xx); + y = xy / x; + z = xz / x; + } + } else if (yy > zz) { + // m22 is the largest diagonal term + if (yy < epsilon) { + x = 0.707106781; + y = 0; + z = 0.707106781; + } else { + y = Math.sqrt(yy); + x = xy / y; + z = yz / y; + } + } else { + // m33 is the largest diagonal term so base result on this + if (zz < epsilon) { + x = 0.707106781; + y = 0.707106781; + z = 0; + } else { + z = Math.sqrt(zz); + x = xz / z; + y = yz / z; + } + } - }, + this.set(x, y, z, angle); + return this; // return 180 deg rotation + } // as we have reached here there are no singularities so we can handle normally - lerp: function ( color, alpha ) { - this.r += ( color.r - this.r ) * alpha; - this.g += ( color.g - this.g ) * alpha; - this.b += ( color.b - this.b ) * alpha; + var s = Math.sqrt((m32 - m23) * (m32 - m23) + (m13 - m31) * (m13 - m31) + (m21 - m12) * (m21 - m12)); // used to normalize - return this; + if (Math.abs(s) < 0.001) s = 1; // prevent divide by zero, should not happen if matrix is orthogonal and should be + // caught by singularity test above, but I've left it in just in case - }, + this.x = (m32 - m23) / s; + this.y = (m13 - m31) / s; + this.z = (m21 - m12) / s; + this.w = Math.acos((m11 + m22 + m33 - 1) / 2); + return this; + }; - equals: function ( c ) { + _proto.min = function 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); + this.w = Math.min(this.w, v.w); + return this; + }; - return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); + _proto.max = function 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); + this.w = Math.max(this.w, v.w); + return this; + }; - }, + _proto.clamp = function 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)); + this.w = Math.max(min.w, Math.min(max.w, this.w)); + return this; + }; - fromArray: function ( array ) { + _proto.clampScalar = function 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)); + this.w = Math.max(minVal, Math.min(maxVal, this.w)); + return this; + }; - this.r = array[ 0 ]; - this.g = array[ 1 ]; - this.b = array[ 2 ]; + _proto.clampLength = function clampLength(min, max) { + var length = this.length(); + return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); + }; - return this; + _proto.floor = function floor() { + this.x = Math.floor(this.x); + this.y = Math.floor(this.y); + this.z = Math.floor(this.z); + this.w = Math.floor(this.w); + return this; + }; - }, + _proto.ceil = function ceil() { + this.x = Math.ceil(this.x); + this.y = Math.ceil(this.y); + this.z = Math.ceil(this.z); + this.w = Math.ceil(this.w); + return this; + }; - toArray: function () { + _proto.round = function round() { + this.x = Math.round(this.x); + this.y = Math.round(this.y); + this.z = Math.round(this.z); + this.w = Math.round(this.w); + return this; + }; - return [ this.r, this.g, this.b ]; + _proto.roundToZero = function 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); + this.w = this.w < 0 ? Math.ceil(this.w) : Math.floor(this.w); + return this; + }; - }, + _proto.negate = function negate() { + this.x = -this.x; + this.y = -this.y; + this.z = -this.z; + this.w = -this.w; + return this; + }; - clone: function () { + _proto.dot = function dot(v) { + return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; + }; - return new THREE.Color().setRGB( this.r, this.g, this.b ); + _proto.lengthSq = function lengthSq() { + return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; + }; - } + _proto.length = function length() { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); + }; -}; + _proto.manhattanLength = function manhattanLength() { + return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w); + }; -THREE.ColorKeywords = { "aliceblue": 0xF0F8FF, "antiquewhite": 0xFAEBD7, "aqua": 0x00FFFF, "aquamarine": 0x7FFFD4, "azure": 0xF0FFFF, -"beige": 0xF5F5DC, "bisque": 0xFFE4C4, "black": 0x000000, "blanchedalmond": 0xFFEBCD, "blue": 0x0000FF, "blueviolet": 0x8A2BE2, -"brown": 0xA52A2A, "burlywood": 0xDEB887, "cadetblue": 0x5F9EA0, "chartreuse": 0x7FFF00, "chocolate": 0xD2691E, "coral": 0xFF7F50, -"cornflowerblue": 0x6495ED, "cornsilk": 0xFFF8DC, "crimson": 0xDC143C, "cyan": 0x00FFFF, "darkblue": 0x00008B, "darkcyan": 0x008B8B, -"darkgoldenrod": 0xB8860B, "darkgray": 0xA9A9A9, "darkgreen": 0x006400, "darkgrey": 0xA9A9A9, "darkkhaki": 0xBDB76B, "darkmagenta": 0x8B008B, -"darkolivegreen": 0x556B2F, "darkorange": 0xFF8C00, "darkorchid": 0x9932CC, "darkred": 0x8B0000, "darksalmon": 0xE9967A, "darkseagreen": 0x8FBC8F, -"darkslateblue": 0x483D8B, "darkslategray": 0x2F4F4F, "darkslategrey": 0x2F4F4F, "darkturquoise": 0x00CED1, "darkviolet": 0x9400D3, -"deeppink": 0xFF1493, "deepskyblue": 0x00BFFF, "dimgray": 0x696969, "dimgrey": 0x696969, "dodgerblue": 0x1E90FF, "firebrick": 0xB22222, -"floralwhite": 0xFFFAF0, "forestgreen": 0x228B22, "fuchsia": 0xFF00FF, "gainsboro": 0xDCDCDC, "ghostwhite": 0xF8F8FF, "gold": 0xFFD700, -"goldenrod": 0xDAA520, "gray": 0x808080, "green": 0x008000, "greenyellow": 0xADFF2F, "grey": 0x808080, "honeydew": 0xF0FFF0, "hotpink": 0xFF69B4, -"indianred": 0xCD5C5C, "indigo": 0x4B0082, "ivory": 0xFFFFF0, "khaki": 0xF0E68C, "lavender": 0xE6E6FA, "lavenderblush": 0xFFF0F5, "lawngreen": 0x7CFC00, -"lemonchiffon": 0xFFFACD, "lightblue": 0xADD8E6, "lightcoral": 0xF08080, "lightcyan": 0xE0FFFF, "lightgoldenrodyellow": 0xFAFAD2, "lightgray": 0xD3D3D3, -"lightgreen": 0x90EE90, "lightgrey": 0xD3D3D3, "lightpink": 0xFFB6C1, "lightsalmon": 0xFFA07A, "lightseagreen": 0x20B2AA, "lightskyblue": 0x87CEFA, -"lightslategray": 0x778899, "lightslategrey": 0x778899, "lightsteelblue": 0xB0C4DE, "lightyellow": 0xFFFFE0, "lime": 0x00FF00, "limegreen": 0x32CD32, -"linen": 0xFAF0E6, "magenta": 0xFF00FF, "maroon": 0x800000, "mediumaquamarine": 0x66CDAA, "mediumblue": 0x0000CD, "mediumorchid": 0xBA55D3, -"mediumpurple": 0x9370DB, "mediumseagreen": 0x3CB371, "mediumslateblue": 0x7B68EE, "mediumspringgreen": 0x00FA9A, "mediumturquoise": 0x48D1CC, -"mediumvioletred": 0xC71585, "midnightblue": 0x191970, "mintcream": 0xF5FFFA, "mistyrose": 0xFFE4E1, "moccasin": 0xFFE4B5, "navajowhite": 0xFFDEAD, -"navy": 0x000080, "oldlace": 0xFDF5E6, "olive": 0x808000, "olivedrab": 0x6B8E23, "orange": 0xFFA500, "orangered": 0xFF4500, "orchid": 0xDA70D6, -"palegoldenrod": 0xEEE8AA, "palegreen": 0x98FB98, "paleturquoise": 0xAFEEEE, "palevioletred": 0xDB7093, "papayawhip": 0xFFEFD5, "peachpuff": 0xFFDAB9, -"peru": 0xCD853F, "pink": 0xFFC0CB, "plum": 0xDDA0DD, "powderblue": 0xB0E0E6, "purple": 0x800080, "red": 0xFF0000, "rosybrown": 0xBC8F8F, -"royalblue": 0x4169E1, "saddlebrown": 0x8B4513, "salmon": 0xFA8072, "sandybrown": 0xF4A460, "seagreen": 0x2E8B57, "seashell": 0xFFF5EE, -"sienna": 0xA0522D, "silver": 0xC0C0C0, "skyblue": 0x87CEEB, "slateblue": 0x6A5ACD, "slategray": 0x708090, "slategrey": 0x708090, "snow": 0xFFFAFA, -"springgreen": 0x00FF7F, "steelblue": 0x4682B4, "tan": 0xD2B48C, "teal": 0x008080, "thistle": 0xD8BFD8, "tomato": 0xFF6347, "turquoise": 0x40E0D0, -"violet": 0xEE82EE, "wheat": 0xF5DEB3, "white": 0xFFFFFF, "whitesmoke": 0xF5F5F5, "yellow": 0xFFFF00, "yellowgreen": 0x9ACD32 }; + _proto.normalize = function normalize() { + return this.divideScalar(this.length() || 1); + }; -/** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - * @author WestLangley / http://github.com/WestLangley - * @author bhouston / http://exocortex.com - */ + _proto.setLength = function setLength(length) { + return this.normalize().multiplyScalar(length); + }; -THREE.Quaternion = function ( x, y, z, w ) { + _proto.lerp = function lerp(v, alpha) { + this.x += (v.x - this.x) * alpha; + this.y += (v.y - this.y) * alpha; + this.z += (v.z - this.z) * alpha; + this.w += (v.w - this.w) * alpha; + return this; + }; - this._x = x || 0; - this._y = y || 0; - this._z = z || 0; - this._w = ( w !== undefined ) ? w : 1; + _proto.lerpVectors = function 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; + this.w = v1.w + (v2.w - v1.w) * alpha; + return this; + }; -}; + _proto.equals = function equals(v) { + return v.x === this.x && v.y === this.y && v.z === this.z && v.w === this.w; + }; -THREE.Quaternion.prototype = { + _proto.fromArray = function fromArray(array, offset) { + if (offset === void 0) { + offset = 0; + } - constructor: THREE.Quaternion, + this.x = array[offset]; + this.y = array[offset + 1]; + this.z = array[offset + 2]; + this.w = array[offset + 3]; + return this; + }; - _x: 0,_y: 0, _z: 0, _w: 0, + _proto.toArray = function toArray(array, offset) { + if (array === void 0) { + array = []; + } - get x () { + if (offset === void 0) { + offset = 0; + } - return this._x; + array[offset] = this.x; + array[offset + 1] = this.y; + array[offset + 2] = this.z; + array[offset + 3] = this.w; + return array; + }; - }, + _proto.fromBufferAttribute = function fromBufferAttribute(attribute, index, offset) { + if (offset !== undefined) { + console.warn('THREE.Vector4: offset has been removed from .fromBufferAttribute().'); + } - set x ( value ) { + this.x = attribute.getX(index); + this.y = attribute.getY(index); + this.z = attribute.getZ(index); + this.w = attribute.getW(index); + return this; + }; - this._x = value; - this.onChangeCallback(); + _proto.random = function random() { + this.x = Math.random(); + this.y = Math.random(); + this.z = Math.random(); + this.w = Math.random(); + return this; + }; - }, + _createClass(Vector4, [{ + key: "width", + get: function get() { + return this.z; + }, + set: function set(value) { + this.z = value; + } + }, { + key: "height", + get: function get() { + return this.w; + }, + set: function set(value) { + this.w = value; + } + }]); + + return Vector4; + }(); - get y () { + /* + In options, we can specify: + * Texture parameters for an auto-generated target texture + * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers + */ - return this._y; + function WebGLRenderTarget(width, height, options) { + this.width = width; + this.height = height; + this.scissor = new Vector4(0, 0, width, height); + this.scissorTest = false; + this.viewport = new Vector4(0, 0, width, height); + options = options || {}; + this.texture = new Texture(undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); + this.texture.image = {}; + this.texture.image.width = width; + this.texture.image.height = height; + this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; + this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; + this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; + this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false; + this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; + } + + WebGLRenderTarget.prototype = Object.assign(Object.create(EventDispatcher.prototype), { + constructor: WebGLRenderTarget, + isWebGLRenderTarget: true, + setSize: function setSize(width, height) { + if (this.width !== width || this.height !== height) { + this.width = width; + this.height = height; + this.texture.image.width = width; + this.texture.image.height = height; + this.dispose(); + } + + this.viewport.set(0, 0, width, height); + this.scissor.set(0, 0, width, height); + }, + clone: function clone() { + return new this.constructor().copy(this); + }, + copy: function copy(source) { + this.width = source.width; + this.height = source.height; + this.viewport.copy(source.viewport); + this.texture = source.texture.clone(); + this.depthBuffer = source.depthBuffer; + this.stencilBuffer = source.stencilBuffer; + this.depthTexture = source.depthTexture; + return this; + }, + dispose: function dispose() { + this.dispatchEvent({ + type: 'dispose' + }); + } + }); - }, + function WebGLMultisampleRenderTarget(width, height, options) { + WebGLRenderTarget.call(this, width, height, options); + this.samples = 4; + } - set y ( value ) { + WebGLMultisampleRenderTarget.prototype = Object.assign(Object.create(WebGLRenderTarget.prototype), { + constructor: WebGLMultisampleRenderTarget, + isWebGLMultisampleRenderTarget: true, + copy: function copy(source) { + WebGLRenderTarget.prototype.copy.call(this, source); + this.samples = source.samples; + return this; + } + }); - this._y = value; - this.onChangeCallback(); + var Quaternion = /*#__PURE__*/function () { + function Quaternion(x, y, z, w) { + if (x === void 0) { + x = 0; + } - }, + if (y === void 0) { + y = 0; + } - get z () { + if (z === void 0) { + z = 0; + } - return this._z; + if (w === void 0) { + w = 1; + } - }, + Object.defineProperty(this, 'isQuaternion', { + value: true + }); + this._x = x; + this._y = y; + this._z = z; + this._w = w; + } - set z ( value ) { + Quaternion.slerp = function slerp(qa, qb, qm, t) { + return qm.copy(qa).slerp(qb, t); + }; - this._z = value; - this.onChangeCallback(); + Quaternion.slerpFlat = function slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) { + // fuzz-free, array-based Quaternion SLERP operation + var x0 = src0[srcOffset0 + 0], + y0 = src0[srcOffset0 + 1], + z0 = src0[srcOffset0 + 2], + w0 = src0[srcOffset0 + 3]; + var x1 = src1[srcOffset1 + 0], + y1 = src1[srcOffset1 + 1], + z1 = src1[srcOffset1 + 2], + w1 = src1[srcOffset1 + 3]; + + if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) { + var s = 1 - t; + var 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) { + var sin = Math.sqrt(sqrSin), + len = Math.atan2(sin, cos * dir); + s = Math.sin(s * len) / sin; + t = Math.sin(t * len) / sin; + } - }, + var 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) { + var f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0); + x0 *= f; + y0 *= f; + z0 *= f; + w0 *= f; + } + } - get w () { + dst[dstOffset] = x0; + dst[dstOffset + 1] = y0; + dst[dstOffset + 2] = z0; + dst[dstOffset + 3] = w0; + }; - return this._w; + Quaternion.multiplyQuaternionsFlat = function multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) { + var x0 = src0[srcOffset0]; + var y0 = src0[srcOffset0 + 1]; + var z0 = src0[srcOffset0 + 2]; + var w0 = src0[srcOffset0 + 3]; + var x1 = src1[srcOffset1]; + var y1 = src1[srcOffset1 + 1]; + var z1 = src1[srcOffset1 + 2]; + var 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; + }; - }, + var _proto = Quaternion.prototype; - set w ( value ) { + _proto.set = function set(x, y, z, w) { + this._x = x; + this._y = y; + this._z = z; + this._w = w; - this._w = value; - this.onChangeCallback(); + this._onChangeCallback(); - }, + return this; + }; - set: function ( x, y, z, w ) { + _proto.clone = function clone() { + return new this.constructor(this._x, this._y, this._z, this._w); + }; - this._x = x; - this._y = y; - this._z = z; - this._w = w; + _proto.copy = function copy(quaternion) { + this._x = quaternion.x; + this._y = quaternion.y; + this._z = quaternion.z; + this._w = quaternion.w; - this.onChangeCallback(); + this._onChangeCallback(); - return this; + return this; + }; - }, + _proto.setFromEuler = function setFromEuler(euler, update) { + if (!(euler && euler.isEuler)) { + throw new Error('THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.'); + } + + var 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 + + var cos = Math.cos; + var sin = Math.sin; + var c1 = cos(x / 2); + var c2 = cos(y / 2); + var c3 = cos(z / 2); + var s1 = sin(x / 2); + var s2 = sin(y / 2); + var 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; - copy: function ( quaternion ) { + 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; - this._x = quaternion._x; - this._y = quaternion._y; - this._z = quaternion._z; - this._w = quaternion._w; + 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; - this.onChangeCallback(); + 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; - return this; + 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; - setFromEuler: function ( euler, update ) { + default: + console.warn('THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order); + } - if ( euler instanceof THREE.Euler === false ) { + if (update !== false) this._onChangeCallback(); + return this; + }; - throw new Error( 'ERROR: Quaternion\'s .setFromEuler() now expects a Euler rotation rather than a Vector3 and order. Please update your code.' ); - } + _proto.setFromAxisAngle = function setFromAxisAngle(axis, angle) { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + // assumes axis is normalized + var 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); - // http://www.mathworks.com/matlabcentral/fileexchange/ - // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ - // content/SpinCalc.m + this._onChangeCallback(); - var c1 = Math.cos( euler._x / 2 ); - var c2 = Math.cos( euler._y / 2 ); - var c3 = Math.cos( euler._z / 2 ); - var s1 = Math.sin( euler._x / 2 ); - var s2 = Math.sin( euler._y / 2 ); - var s3 = Math.sin( euler._z / 2 ); + return this; + }; - if ( euler.order === 'XYZ' ) { + _proto.setFromRotationMatrix = function 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) + var 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) { + var 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) { + var _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) { + var _s2 = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33); + + this._w = (m13 - m31) / _s2; + this._x = (m12 + m21) / _s2; + this._y = 0.25 * _s2; + this._z = (m23 + m32) / _s2; + } else { + var _s3 = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22); - 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; + this._w = (m21 - m12) / _s3; + this._x = (m13 + m31) / _s3; + this._y = (m23 + m32) / _s3; + this._z = 0.25 * _s3; + } - } else if ( euler.order === 'YXZ' ) { + this._onChangeCallback(); - 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; + return this; + }; - } else if ( euler.order === 'ZXY' ) { + _proto.setFromUnitVectors = function setFromUnitVectors(vFrom, vTo) { + // assumes direction vectors vFrom and vTo are normalized + var EPS = 0.000001; + var r = vFrom.dot(vTo) + 1; - 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; + if (r < EPS) { + r = 0; - } else if ( euler.order === 'ZYX' ) { + 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; + } - 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; + return this.normalize(); + }; - } else if ( euler.order === 'YZX' ) { + _proto.angleTo = function angleTo(q) { + return 2 * Math.acos(Math.abs(MathUtils.clamp(this.dot(q), -1, 1))); + }; - 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; + _proto.rotateTowards = function rotateTowards(q, step) { + var angle = this.angleTo(q); + if (angle === 0) return this; + var t = Math.min(1, step / angle); + this.slerp(q, t); + return this; + }; - } else if ( euler.order === 'XZY' ) { + _proto.identity = function identity() { + return this.set(0, 0, 0, 1); + }; - 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; + _proto.inverse = function inverse() { + // quaternion is assumed to have unit length + return this.conjugate(); + }; - } + _proto.conjugate = function conjugate() { + this._x *= -1; + this._y *= -1; + this._z *= -1; - if ( update !== false ) this.onChangeCallback(); + this._onChangeCallback(); - return this; + return this; + }; - }, + _proto.dot = function dot(v) { + return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; + }; - setFromAxisAngle: function ( axis, angle ) { + _proto.lengthSq = function lengthSq() { + return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; + }; - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + _proto.length = function length() { + return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w); + }; - // assumes axis is normalized + _proto.normalize = function normalize() { + var l = this.length(); - var halfAngle = angle / 2, s = Math.sin( halfAngle ); + 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._x = axis.x * s; - this._y = axis.y * s; - this._z = axis.z * s; - this._w = Math.cos( halfAngle ); + this._onChangeCallback(); - this.onChangeCallback(); + return this; + }; - return this; + _proto.multiply = function 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); + }; - setFromRotationMatrix: function ( m ) { + _proto.premultiply = function premultiply(q) { + return this.multiplyQuaternions(q, this); + }; - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + _proto.multiplyQuaternions = function multiplyQuaternions(a, b) { + // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + var qax = a._x, + qay = a._y, + qaz = a._z, + qaw = a._w; + var 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(); - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + return this; + }; - var te = m.elements, + _proto.slerp = function slerp(qb, t) { + if (t === 0) return this; + if (t === 1) return this.copy(qb); + var x = this._x, + y = this._y, + z = this._z, + w = this._w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + + var 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); + } - 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], + if (cosHalfTheta >= 1.0) { + this._w = w; + this._x = x; + this._y = y; + this._z = z; + return this; + } - trace = m11 + m22 + m33, - s; + var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; - if ( trace > 0 ) { + if (sqrSinHalfTheta <= Number.EPSILON) { + var 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(); - s = 0.5 / Math.sqrt( trace + 1.0 ); + this._onChangeCallback(); - this._w = 0.25 / s; - this._x = ( m32 - m23 ) * s; - this._y = ( m13 - m31 ) * s; - this._z = ( m21 - m12 ) * s; + return this; + } - } else if ( m11 > m22 && m11 > m33 ) { + var sinHalfTheta = Math.sqrt(sqrSinHalfTheta); + var halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta); + var 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; - s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); + this._onChangeCallback(); - this._w = (m32 - m23 ) / s; - this._x = 0.25 * s; - this._y = (m12 + m21 ) / s; - this._z = (m13 + m31 ) / s; + return this; + }; - } else if ( m22 > m33 ) { + _proto.equals = function equals(quaternion) { + return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w; + }; - s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); + _proto.fromArray = function fromArray(array, offset) { + if (offset === void 0) { + offset = 0; + } - this._w = (m13 - m31 ) / s; - this._x = (m12 + m21 ) / s; - this._y = 0.25 * s; - this._z = (m23 + m32 ) / s; + this._x = array[offset]; + this._y = array[offset + 1]; + this._z = array[offset + 2]; + this._w = array[offset + 3]; - } else { + this._onChangeCallback(); - s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); + return this; + }; - this._w = ( m21 - m12 ) / s; - this._x = ( m13 + m31 ) / s; - this._y = ( m23 + m32 ) / s; - this._z = 0.25 * s; + _proto.toArray = function toArray(array, offset) { + if (array === void 0) { + array = []; + } - } + if (offset === void 0) { + offset = 0; + } - this.onChangeCallback(); + array[offset] = this._x; + array[offset + 1] = this._y; + array[offset + 2] = this._z; + array[offset + 3] = this._w; + return array; + }; - return this; + _proto.fromBufferAttribute = function 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; + }; - }, + _proto._onChange = function _onChange(callback) { + this._onChangeCallback = callback; + return this; + }; - setFromUnitVectors: function () { + _proto._onChangeCallback = function _onChangeCallback() {}; - // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final + _createClass(Quaternion, [{ + key: "x", + get: function get() { + return this._x; + }, + set: function set(value) { + this._x = value; - // assumes direction vectors vFrom and vTo are normalized + this._onChangeCallback(); + } + }, { + key: "y", + get: function get() { + return this._y; + }, + set: function set(value) { + this._y = value; - var v1, r; + this._onChangeCallback(); + } + }, { + key: "z", + get: function get() { + return this._z; + }, + set: function set(value) { + this._z = value; - var EPS = 0.000001; + this._onChangeCallback(); + } + }, { + key: "w", + get: function get() { + return this._w; + }, + set: function set(value) { + this._w = value; - return function( vFrom, vTo ) { + this._onChangeCallback(); + } + }]); - if ( v1 === undefined ) v1 = new THREE.Vector3(); + return Quaternion; + }(); - r = vFrom.dot( vTo ) + 1; + var Vector3 = /*#__PURE__*/function () { + function Vector3(x, y, z) { + if (x === void 0) { + x = 0; + } - if ( r < EPS ) { + if (y === void 0) { + y = 0; + } - r = 0; + if (z === void 0) { + z = 0; + } - if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { + Object.defineProperty(this, 'isVector3', { + value: true + }); + this.x = x; + this.y = y; + this.z = z; + } - v1.set( - vFrom.y, vFrom.x, 0 ); + var _proto = Vector3.prototype; - } else { + _proto.set = function set(x, y, z) { + if (z === undefined) z = this.z; // sprite.scale.set(x,y) - v1.set( 0, - vFrom.z, vFrom.y ); + this.x = x; + this.y = y; + this.z = z; + return this; + }; - } + _proto.setScalar = function setScalar(scalar) { + this.x = scalar; + this.y = scalar; + this.z = scalar; + return this; + }; - } else { + _proto.setX = function setX(x) { + this.x = x; + return this; + }; - v1.crossVectors( vFrom, vTo ); + _proto.setY = function setY(y) { + this.y = y; + return this; + }; - } + _proto.setZ = function setZ(z) { + this.z = z; + return this; + }; - this._x = v1.x; - this._y = v1.y; - this._z = v1.z; - this._w = r; + _proto.setComponent = function setComponent(index, value) { + switch (index) { + case 0: + this.x = value; + break; + + case 1: + this.y = value; + break; + + case 2: + this.z = value; + break; - this.normalize(); + default: + throw new Error('index is out of range: ' + index); + } return this; + }; - } + _proto.getComponent = function getComponent(index) { + switch (index) { + case 0: + return this.x; - }(), + case 1: + return this.y; - inverse: function () { + case 2: + return this.z; - this.conjugate().normalize(); + default: + throw new Error('index is out of range: ' + index); + } + }; - return this; + _proto.clone = function clone() { + return new this.constructor(this.x, this.y, this.z); + }; - }, + _proto.copy = function copy(v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + return this; + }; - conjugate: function () { + _proto.add = function 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 *= -1; - this._y *= -1; - this._z *= -1; + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; + }; - this.onChangeCallback(); + _proto.addScalar = function addScalar(s) { + this.x += s; + this.y += s; + this.z += s; + return this; + }; - return this; + _proto.addVectors = function addVectors(a, b) { + this.x = a.x + b.x; + this.y = a.y + b.y; + this.z = a.z + b.z; + return this; + }; - }, + _proto.addScaledVector = function addScaledVector(v, s) { + this.x += v.x * s; + this.y += v.y * s; + this.z += v.z * s; + return this; + }; - lengthSq: function () { + _proto.sub = function 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); + } - return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + return this; + }; - }, + _proto.subScalar = function subScalar(s) { + this.x -= s; + this.y -= s; + this.z -= s; + return this; + }; - length: function () { + _proto.subVectors = function subVectors(a, b) { + this.x = a.x - b.x; + this.y = a.y - b.y; + this.z = a.z - b.z; + return this; + }; - return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w ); + _proto.multiply = function 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; + }; - normalize: function () { + _proto.multiplyScalar = function multiplyScalar(scalar) { + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + return this; + }; - var l = this.length(); + _proto.multiplyVectors = function multiplyVectors(a, b) { + this.x = a.x * b.x; + this.y = a.y * b.y; + this.z = a.z * b.z; + return this; + }; - if ( l === 0 ) { + _proto.applyEuler = function applyEuler(euler) { + if (!(euler && euler.isEuler)) { + console.error('THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.'); + } - this._x = 0; - this._y = 0; - this._z = 0; - this._w = 1; + return this.applyQuaternion(_quaternion.setFromEuler(euler)); + }; - } else { + _proto.applyAxisAngle = function applyAxisAngle(axis, angle) { + return this.applyQuaternion(_quaternion.setFromAxisAngle(axis, angle)); + }; - l = 1 / l; + _proto.applyMatrix3 = function applyMatrix3(m) { + var x = this.x, + y = this.y, + z = this.z; + var 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; + }; - this._x = this._x * l; - this._y = this._y * l; - this._z = this._z * l; - this._w = this._w * l; + _proto.applyNormalMatrix = function applyNormalMatrix(m) { + return this.applyMatrix3(m).normalize(); + }; - } + _proto.applyMatrix4 = function applyMatrix4(m) { + var x = this.x, + y = this.y, + z = this.z; + var e = m.elements; + var 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; + }; - this.onChangeCallback(); + _proto.applyQuaternion = function applyQuaternion(q) { + var x = this.x, + y = this.y, + z = this.z; + var qx = q.x, + qy = q.y, + qz = q.z, + qw = q.w; // calculate quat * vector + + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var 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; + }; - return this; + _proto.project = function project(camera) { + return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix); + }; - }, + _proto.unproject = function unproject(camera) { + return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld); + }; - multiply: function ( q, p ) { + _proto.transformDirection = function transformDirection(m) { + // input: THREE.Matrix4 affine matrix + // vector interpreted as a direction + var x = this.x, + y = this.y, + z = this.z; + var 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(); + }; - if ( p !== undefined ) { + _proto.divide = function divide(v) { + this.x /= v.x; + this.y /= v.y; + this.z /= v.z; + return this; + }; - console.warn( 'DEPRECATED: Quaternion\'s .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); - return this.multiplyQuaternions( q, p ); + _proto.divideScalar = function divideScalar(scalar) { + return this.multiplyScalar(1 / scalar); + }; - } + _proto.min = function 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; + }; - return this.multiplyQuaternions( this, q ); + _proto.max = function 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; + }; - }, + _proto.clamp = function 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; + }; - multiplyQuaternions: function ( a, b ) { + _proto.clampScalar = function 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; + }; - // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + _proto.clampLength = function clampLength(min, max) { + var length = this.length(); + return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); + }; - var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; - var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; + _proto.floor = function floor() { + this.x = Math.floor(this.x); + this.y = Math.floor(this.y); + this.z = Math.floor(this.z); + return this; + }; - 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; + _proto.ceil = function ceil() { + this.x = Math.ceil(this.x); + this.y = Math.ceil(this.y); + this.z = Math.ceil(this.z); + return this; + }; - this.onChangeCallback(); + _proto.round = function round() { + this.x = Math.round(this.x); + this.y = Math.round(this.y); + this.z = Math.round(this.z); + return this; + }; - return this; + _proto.roundToZero = function 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; + }; - }, + _proto.negate = function negate() { + this.x = -this.x; + this.y = -this.y; + this.z = -this.z; + return this; + }; - multiplyVector3: function ( vector ) { + _proto.dot = function dot(v) { + return this.x * v.x + this.y * v.y + this.z * v.z; + } // TODO lengthSquared? + ; - console.warn( 'DEPRECATED: Quaternion\'s .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); - return vector.applyQuaternion( this ); + _proto.lengthSq = function lengthSq() { + return this.x * this.x + this.y * this.y + this.z * this.z; + }; - }, + _proto.length = function length() { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + }; - slerp: function ( qb, t ) { + _proto.manhattanLength = function manhattanLength() { + return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z); + }; - var x = this._x, y = this._y, z = this._z, w = this._w; + _proto.normalize = function normalize() { + return this.divideScalar(this.length() || 1); + }; - // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + _proto.setLength = function setLength(length) { + return this.normalize().multiplyScalar(length); + }; - var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; + _proto.lerp = function 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; + }; - if ( cosHalfTheta < 0 ) { + _proto.lerpVectors = function 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; + }; - this._w = -qb._w; - this._x = -qb._x; - this._y = -qb._y; - this._z = -qb._z; + _proto.cross = function 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); + } - cosHalfTheta = -cosHalfTheta; + return this.crossVectors(this, v); + }; - } else { + _proto.crossVectors = function crossVectors(a, b) { + var ax = a.x, + ay = a.y, + az = a.z; + var 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; + }; - this.copy( qb ); + _proto.projectOnVector = function projectOnVector(v) { + var denominator = v.lengthSq(); + if (denominator === 0) return this.set(0, 0, 0); + var scalar = v.dot(this) / denominator; + return this.copy(v).multiplyScalar(scalar); + }; - } + _proto.projectOnPlane = function projectOnPlane(planeNormal) { + _vector.copy(this).projectOnVector(planeNormal); - if ( cosHalfTheta >= 1.0 ) { + return this.sub(_vector); + }; - this._w = w; - this._x = x; - this._y = y; - this._z = z; + _proto.reflect = function 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))); + }; - return this; + _proto.angleTo = function angleTo(v) { + var denominator = Math.sqrt(this.lengthSq() * v.lengthSq()); + if (denominator === 0) return Math.PI / 2; + var theta = this.dot(v) / denominator; // clamp, to handle numerical problems - } + return Math.acos(MathUtils.clamp(theta, -1, 1)); + }; - var halfTheta = Math.acos( cosHalfTheta ); - var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta ); + _proto.distanceTo = function distanceTo(v) { + return Math.sqrt(this.distanceToSquared(v)); + }; + + _proto.distanceToSquared = function distanceToSquared(v) { + var dx = this.x - v.x, + dy = this.y - v.y, + dz = this.z - v.z; + return dx * dx + dy * dy + dz * dz; + }; - if ( Math.abs( sinHalfTheta ) < 0.001 ) { + _proto.manhattanDistanceTo = function manhattanDistanceTo(v) { + return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z); + }; - this._w = 0.5 * ( w + this._w ); - this._x = 0.5 * ( x + this._x ); - this._y = 0.5 * ( y + this._y ); - this._z = 0.5 * ( z + this._z ); + _proto.setFromSpherical = function setFromSpherical(s) { + return this.setFromSphericalCoords(s.radius, s.phi, s.theta); + }; + _proto.setFromSphericalCoords = function setFromSphericalCoords(radius, phi, theta) { + var 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; + }; - } + _proto.setFromCylindrical = function setFromCylindrical(c) { + return this.setFromCylindricalCoords(c.radius, c.theta, c.y); + }; - var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, - ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; + _proto.setFromCylindricalCoords = function setFromCylindricalCoords(radius, theta, y) { + this.x = radius * Math.sin(theta); + this.y = y; + this.z = radius * Math.cos(theta); + return this; + }; - 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 ); + _proto.setFromMatrixPosition = function setFromMatrixPosition(m) { + var e = m.elements; + this.x = e[12]; + this.y = e[13]; + this.z = e[14]; + return this; + }; - this.onChangeCallback(); + _proto.setFromMatrixScale = function setFromMatrixScale(m) { + var sx = this.setFromMatrixColumn(m, 0).length(); + var sy = this.setFromMatrixColumn(m, 1).length(); + var sz = this.setFromMatrixColumn(m, 2).length(); + this.x = sx; + this.y = sy; + this.z = sz; + return this; + }; - return this; + _proto.setFromMatrixColumn = function setFromMatrixColumn(m, index) { + return this.fromArray(m.elements, index * 4); + }; - }, + _proto.setFromMatrix3Column = function setFromMatrix3Column(m, index) { + return this.fromArray(m.elements, index * 3); + }; - equals: function ( quaternion ) { + _proto.equals = function equals(v) { + return v.x === this.x && v.y === this.y && v.z === this.z; + }; - return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); + _proto.fromArray = function fromArray(array, offset) { + if (offset === void 0) { + offset = 0; + } - }, + this.x = array[offset]; + this.y = array[offset + 1]; + this.z = array[offset + 2]; + return this; + }; - fromArray: function ( array ) { + _proto.toArray = function toArray(array, offset) { + if (array === void 0) { + array = []; + } - this._x = array[ 0 ]; - this._y = array[ 1 ]; - this._z = array[ 2 ]; - this._w = array[ 3 ]; + if (offset === void 0) { + offset = 0; + } - this.onChangeCallback(); + array[offset] = this.x; + array[offset + 1] = this.y; + array[offset + 2] = this.z; + return array; + }; - return this; + _proto.fromBufferAttribute = function 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; + }; - toArray: function () { + _proto.random = function random() { + this.x = Math.random(); + this.y = Math.random(); + this.z = Math.random(); + return this; + }; - return [ this._x, this._y, this._z, this._w ]; + return Vector3; + }(); - }, + var _vector = /*@__PURE__*/new Vector3(); - onChange: function ( callback ) { + var _quaternion = /*@__PURE__*/new Quaternion(); - this.onChangeCallback = callback; + var Box3 = /*#__PURE__*/function () { + function Box3(min, max) { + Object.defineProperty(this, 'isBox3', { + value: true + }); + this.min = min !== undefined ? min : new Vector3(+Infinity, +Infinity, +Infinity); + this.max = max !== undefined ? max : new Vector3(-Infinity, -Infinity, -Infinity); + } - return this; + var _proto = Box3.prototype; - }, + _proto.set = function set(min, max) { + this.min.copy(min); + this.max.copy(max); + return this; + }; - onChangeCallback: function () {}, + _proto.setFromArray = function setFromArray(array) { + var minX = +Infinity; + var minY = +Infinity; + var minZ = +Infinity; + var maxX = -Infinity; + var maxY = -Infinity; + var maxZ = -Infinity; + + for (var i = 0, l = array.length; i < l; i += 3) { + var x = array[i]; + var y = array[i + 1]; + var z = array[i + 2]; + if (x < minX) minX = x; + if (y < minY) minY = y; + if (z < minZ) minZ = z; + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; + if (z > maxZ) maxZ = z; + } + + this.min.set(minX, minY, minZ); + this.max.set(maxX, maxY, maxZ); + return this; + }; - clone: function () { + _proto.setFromBufferAttribute = function setFromBufferAttribute(attribute) { + var minX = +Infinity; + var minY = +Infinity; + var minZ = +Infinity; + var maxX = -Infinity; + var maxY = -Infinity; + var maxZ = -Infinity; + + for (var i = 0, l = attribute.count; i < l; i++) { + var x = attribute.getX(i); + var y = attribute.getY(i); + var z = attribute.getZ(i); + if (x < minX) minX = x; + if (y < minY) minY = y; + if (z < minZ) minZ = z; + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; + if (z > maxZ) maxZ = z; + } + + this.min.set(minX, minY, minZ); + this.max.set(maxX, maxY, maxZ); + return this; + }; - return new THREE.Quaternion( this._x, this._y, this._z, this._w ); + _proto.setFromPoints = function setFromPoints(points) { + this.makeEmpty(); - } + for (var i = 0, il = points.length; i < il; i++) { + this.expandByPoint(points[i]); + } -}; + return this; + }; -THREE.Quaternion.slerp = function ( qa, qb, qm, t ) { + _proto.setFromCenterAndSize = function setFromCenterAndSize(center, size) { + var halfSize = _vector$1.copy(size).multiplyScalar(0.5); - return qm.copy( qa ).slerp( qb, t ); + this.min.copy(center).sub(halfSize); + this.max.copy(center).add(halfSize); + return this; + }; -} + _proto.setFromObject = function setFromObject(object) { + this.makeEmpty(); + return this.expandByObject(object); + }; -/** - * @author mrdoob / http://mrdoob.com/ - * @author philogb / http://blog.thejit.org/ - * @author egraether / http://egraether.com/ - * @author zz85 / http://www.lab4games.net/zz85/blog - */ + _proto.clone = function clone() { + return new this.constructor().copy(this); + }; -THREE.Vector2 = function ( x, y ) { + _proto.copy = function copy(box) { + this.min.copy(box.min); + this.max.copy(box.max); + return this; + }; - this.x = x || 0; - this.y = y || 0; + _proto.makeEmpty = function makeEmpty() { + this.min.x = this.min.y = this.min.z = +Infinity; + this.max.x = this.max.y = this.max.z = -Infinity; + return this; + }; -}; + _proto.isEmpty = function isEmpty() { + // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes + return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z; + }; -THREE.Vector2.prototype = { + _proto.getCenter = function getCenter(target) { + if (target === undefined) { + console.warn('THREE.Box3: .getCenter() target is now required'); + target = new Vector3(); + } - constructor: THREE.Vector2, + return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); + }; - set: function ( x, y ) { + _proto.getSize = function getSize(target) { + if (target === undefined) { + console.warn('THREE.Box3: .getSize() target is now required'); + target = new Vector3(); + } - this.x = x; - this.y = y; + return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min); + }; - return this; + _proto.expandByPoint = function expandByPoint(point) { + this.min.min(point); + this.max.max(point); + return this; + }; - }, + _proto.expandByVector = function expandByVector(vector) { + this.min.sub(vector); + this.max.add(vector); + return this; + }; - setX: function ( x ) { + _proto.expandByScalar = function expandByScalar(scalar) { + this.min.addScalar(-scalar); + this.max.addScalar(scalar); + return this; + }; - this.x = x; + _proto.expandByObject = function expandByObject(object) { + // Computes the world-axis-aligned bounding box of an object (including its children), + // accounting for both the object's, and children's, world transforms + object.updateWorldMatrix(false, false); + var geometry = object.geometry; - return this; + if (geometry !== undefined) { + if (geometry.boundingBox === null) { + geometry.computeBoundingBox(); + } - }, + _box.copy(geometry.boundingBox); - setY: function ( y ) { + _box.applyMatrix4(object.matrixWorld); - this.y = y; + this.union(_box); + } - return this; + var children = object.children; - }, + for (var i = 0, l = children.length; i < l; i++) { + this.expandByObject(children[i]); + } - setComponent: function ( index, value ) { + return this; + }; - switch ( index ) { + _proto.containsPoint = function containsPoint(point) { + return point.x < this.min.x || point.x > this.max.x || point.y < this.min.y || point.y > this.max.y || point.z < this.min.z || point.z > this.max.z ? false : true; + }; - case 0: this.x = value; break; - case 1: this.y = value; break; - default: throw new Error( "index is out of range: " + index ); + _proto.containsBox = function containsBox(box) { + return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y && this.min.z <= box.min.z && box.max.z <= this.max.z; + }; - } + _proto.getParameter = function getParameter(point, target) { + // This can potentially have a divide by zero if the box + // has a size dimension of 0. + if (target === undefined) { + console.warn('THREE.Box3: .getParameter() target is now required'); + target = new Vector3(); + } - }, + return target.set((point.x - this.min.x) / (this.max.x - this.min.x), (point.y - this.min.y) / (this.max.y - this.min.y), (point.z - this.min.z) / (this.max.z - this.min.z)); + }; - getComponent: function ( index ) { + _proto.intersectsBox = function intersectsBox(box) { + // using 6 splitting planes to rule out intersections. + return box.max.x < this.min.x || box.min.x > this.max.x || box.max.y < this.min.y || box.min.y > this.max.y || box.max.z < this.min.z || box.min.z > this.max.z ? false : true; + }; - switch ( index ) { + _proto.intersectsSphere = function intersectsSphere(sphere) { + // Find the point on the AABB closest to the sphere center. + this.clampPoint(sphere.center, _vector$1); // If that point is inside the sphere, the AABB and sphere intersect. - case 0: return this.x; - case 1: return this.y; - default: throw new Error( "index is out of range: " + index ); + return _vector$1.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius; + }; - } + _proto.intersectsPlane = function intersectsPlane(plane) { + // We compute the minimum and maximum dot product values. If those values + // are on the same side (back or front) of the plane, then there is no intersection. + var min, max; - }, + if (plane.normal.x > 0) { + min = plane.normal.x * this.min.x; + max = plane.normal.x * this.max.x; + } else { + min = plane.normal.x * this.max.x; + max = plane.normal.x * this.min.x; + } - copy: function ( v ) { + if (plane.normal.y > 0) { + min += plane.normal.y * this.min.y; + max += plane.normal.y * this.max.y; + } else { + min += plane.normal.y * this.max.y; + max += plane.normal.y * this.min.y; + } - this.x = v.x; - this.y = v.y; + if (plane.normal.z > 0) { + min += plane.normal.z * this.min.z; + max += plane.normal.z * this.max.z; + } else { + min += plane.normal.z * this.max.z; + max += plane.normal.z * this.min.z; + } - return this; + return min <= -plane.constant && max >= -plane.constant; + }; - }, + _proto.intersectsTriangle = function intersectsTriangle(triangle) { + if (this.isEmpty()) { + return false; + } // compute box center and extents - add: function ( v, w ) { - if ( w !== undefined ) { + this.getCenter(_center); - console.warn( 'DEPRECATED: Vector2\'s .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); + _extents.subVectors(this.max, _center); // translate triangle to aabb origin - } - this.x += v.x; - this.y += v.y; + _v0.subVectors(triangle.a, _center); - return this; + _v1.subVectors(triangle.b, _center); - }, + _v2.subVectors(triangle.c, _center); // compute edge vectors for triangle - addVectors: function ( a, b ) { - this.x = a.x + b.x; - this.y = a.y + b.y; + _f0.subVectors(_v1, _v0); - return this; + _f1.subVectors(_v2, _v1); - }, + _f2.subVectors(_v0, _v2); // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb + // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation + // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) - addScalar: function ( s ) { - this.x += s; - this.y += s; + var axes = [0, -_f0.z, _f0.y, 0, -_f1.z, _f1.y, 0, -_f2.z, _f2.y, _f0.z, 0, -_f0.x, _f1.z, 0, -_f1.x, _f2.z, 0, -_f2.x, -_f0.y, _f0.x, 0, -_f1.y, _f1.x, 0, -_f2.y, _f2.x, 0]; - return this; + if (!satForAxes(axes, _v0, _v1, _v2, _extents)) { + return false; + } // test 3 face normals from the aabb - }, - sub: function ( v, w ) { + axes = [1, 0, 0, 0, 1, 0, 0, 0, 1]; - if ( w !== undefined ) { + if (!satForAxes(axes, _v0, _v1, _v2, _extents)) { + return false; + } // finally testing the face normal of the triangle + // use already existing triangle edge vectors here - console.warn( 'DEPRECATED: Vector2\'s .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); - } + _triangleNormal.crossVectors(_f0, _f1); - this.x -= v.x; - this.y -= v.y; + axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z]; + return satForAxes(axes, _v0, _v1, _v2, _extents); + }; - return this; + _proto.clampPoint = function clampPoint(point, target) { + if (target === undefined) { + console.warn('THREE.Box3: .clampPoint() target is now required'); + target = new Vector3(); + } - }, + return target.copy(point).clamp(this.min, this.max); + }; - subVectors: function ( a, b ) { + _proto.distanceToPoint = function distanceToPoint(point) { + var clampedPoint = _vector$1.copy(point).clamp(this.min, this.max); - this.x = a.x - b.x; - this.y = a.y - b.y; + return clampedPoint.sub(point).length(); + }; - return this; + _proto.getBoundingSphere = function getBoundingSphere(target) { + if (target === undefined) { + console.error('THREE.Box3: .getBoundingSphere() target is now required'); //target = new Sphere(); // removed to avoid cyclic dependency + } - }, - - multiply: function ( v ) { + this.getCenter(target.center); + target.radius = this.getSize(_vector$1).length() * 0.5; + return target; + }; - this.x *= v.x; - this.y *= v.y; + _proto.intersect = function intersect(box) { + this.min.max(box.min); + this.max.min(box.max); // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. - return this; + if (this.isEmpty()) this.makeEmpty(); + return this; + }; - }, + _proto.union = function union(box) { + this.min.min(box.min); + this.max.max(box.max); + return this; + }; - multiplyScalar: function ( s ) { + _proto.applyMatrix4 = function applyMatrix4(matrix) { + // transform of empty box is an empty box. + if (this.isEmpty()) return this; // NOTE: I am using a binary pattern to specify all 2^3 combinations below - this.x *= s; - this.y *= s; + _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix); // 000 - return this; - }, + _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix); // 001 - divide: function ( v ) { - this.x /= v.x; - this.y /= v.y; + _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix); // 010 - return this; - }, + _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix); // 011 - divideScalar: function ( scalar ) { - if ( scalar !== 0 ) { + _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix); // 100 - var invScalar = 1 / scalar; - this.x *= invScalar; - this.y *= invScalar; + _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix); // 101 - } else { - - this.x = 0; - this.y = 0; - - } - return this; - - }, + _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix); // 110 - min: function ( v ) { - if ( this.x > v.x ) { - - this.x = v.x; + _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix); // 111 - } - if ( this.y > v.y ) { + this.setFromPoints(_points); + return this; + }; - this.y = v.y; + _proto.translate = function translate(offset) { + this.min.add(offset); + this.max.add(offset); + return this; + }; - } + _proto.equals = function equals(box) { + return box.min.equals(this.min) && box.max.equals(this.max); + }; - return this; + return Box3; + }(); - }, + function satForAxes(axes, v0, v1, v2, extents) { + for (var i = 0, j = axes.length - 3; i <= j; i += 3) { + _testAxis.fromArray(axes, i); // project the aabb onto the seperating axis - max: function ( v ) { - if ( this.x < v.x ) { + var r = extents.x * Math.abs(_testAxis.x) + extents.y * Math.abs(_testAxis.y) + extents.z * Math.abs(_testAxis.z); // project all 3 vertices of the triangle onto the seperating axis - this.x = v.x; + var p0 = v0.dot(_testAxis); + var p1 = v1.dot(_testAxis); + var p2 = v2.dot(_testAxis); // actual test, basically see if either of the most extreme of the triangle points intersects r + if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) { + // points of the projected triangle are outside the projected half-length of the aabb + // the axis is seperating and we can exit + return false; + } } - if ( this.y < v.y ) { + return true; + } - this.y = v.y; + var _points = [/*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3()]; - } + var _vector$1 = /*@__PURE__*/new Vector3(); - return this; + var _box = /*@__PURE__*/new Box3(); // triangle centered vertices - }, - clamp: function ( min, max ) { + var _v0 = /*@__PURE__*/new Vector3(); - // This function assumes min < max, if this assumption isn't true it will not operate correctly + var _v1 = /*@__PURE__*/new Vector3(); - if ( this.x < min.x ) { + var _v2 = /*@__PURE__*/new Vector3(); // triangle edge vectors - this.x = min.x; - } else if ( this.x > max.x ) { + var _f0 = /*@__PURE__*/new Vector3(); - this.x = max.x; + var _f1 = /*@__PURE__*/new Vector3(); - } + var _f2 = /*@__PURE__*/new Vector3(); - if ( this.y < min.y ) { + var _center = /*@__PURE__*/new Vector3(); - this.y = min.y; + var _extents = /*@__PURE__*/new Vector3(); - } else if ( this.y > max.y ) { + var _triangleNormal = /*@__PURE__*/new Vector3(); - this.y = max.y; + var _testAxis = /*@__PURE__*/new Vector3(); - } + var _box$1 = /*@__PURE__*/new Box3(); - return this; - }, + var Sphere = /*#__PURE__*/function () { + function Sphere(center, radius) { + this.center = center !== undefined ? center : new Vector3(); + this.radius = radius !== undefined ? radius : -1; + } - clampScalar: ( function () { + var _proto = Sphere.prototype; - var min, max; + _proto.set = function set(center, radius) { + this.center.copy(center); + this.radius = radius; + return this; + }; - return function ( minVal, maxVal ) { + _proto.setFromPoints = function setFromPoints(points, optionalCenter) { + var center = this.center; - if ( min === undefined ) { + if (optionalCenter !== undefined) { + center.copy(optionalCenter); + } else { + _box$1.setFromPoints(points).getCenter(center); + } - min = new THREE.Vector2(); - max = new THREE.Vector2(); + var maxRadiusSq = 0; + for (var i = 0, il = points.length; i < il; i++) { + maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i])); } - min.set( minVal, minVal ); - max.set( maxVal, maxVal ); - - return this.clamp( min, max ); + this.radius = Math.sqrt(maxRadiusSq); + return this; + }; + _proto.clone = function clone() { + return new this.constructor().copy(this); }; - - } )(), - floor: function () { + _proto.copy = function copy(sphere) { + this.center.copy(sphere.center); + this.radius = sphere.radius; + return this; + }; - this.x = Math.floor( this.x ); - this.y = Math.floor( this.y ); + _proto.isEmpty = function isEmpty() { + return this.radius < 0; + }; - return this; + _proto.makeEmpty = function makeEmpty() { + this.center.set(0, 0, 0); + this.radius = -1; + return this; + }; - }, + _proto.containsPoint = function containsPoint(point) { + return point.distanceToSquared(this.center) <= this.radius * this.radius; + }; - ceil: function () { + _proto.distanceToPoint = function distanceToPoint(point) { + return point.distanceTo(this.center) - this.radius; + }; - this.x = Math.ceil( this.x ); - this.y = Math.ceil( this.y ); + _proto.intersectsSphere = function intersectsSphere(sphere) { + var radiusSum = this.radius + sphere.radius; + return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum; + }; - return this; + _proto.intersectsBox = function intersectsBox(box) { + return box.intersectsSphere(this); + }; - }, + _proto.intersectsPlane = function intersectsPlane(plane) { + return Math.abs(plane.distanceToPoint(this.center)) <= this.radius; + }; - round: function () { + _proto.clampPoint = function clampPoint(point, target) { + var deltaLengthSq = this.center.distanceToSquared(point); - this.x = Math.round( this.x ); - this.y = Math.round( this.y ); + if (target === undefined) { + console.warn('THREE.Sphere: .clampPoint() target is now required'); + target = new Vector3(); + } - return this; + target.copy(point); - }, + if (deltaLengthSq > this.radius * this.radius) { + target.sub(this.center).normalize(); + target.multiplyScalar(this.radius).add(this.center); + } - roundToZero: function () { + return target; + }; - 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 ); + _proto.getBoundingBox = function getBoundingBox(target) { + if (target === undefined) { + console.warn('THREE.Sphere: .getBoundingBox() target is now required'); + target = new Box3(); + } - return this; + if (this.isEmpty()) { + // Empty sphere produces empty bounding box + target.makeEmpty(); + return target; + } - }, + target.set(this.center, this.center); + target.expandByScalar(this.radius); + return target; + }; - negate: function () { + _proto.applyMatrix4 = function applyMatrix4(matrix) { + this.center.applyMatrix4(matrix); + this.radius = this.radius * matrix.getMaxScaleOnAxis(); + return this; + }; - return this.multiplyScalar( - 1 ); + _proto.translate = function translate(offset) { + this.center.add(offset); + return this; + }; - }, + _proto.equals = function equals(sphere) { + return sphere.center.equals(this.center) && sphere.radius === this.radius; + }; - dot: function ( v ) { + return Sphere; + }(); - return this.x * v.x + this.y * v.y; + var _vector$2 = /*@__PURE__*/new Vector3(); - }, + var _segCenter = /*@__PURE__*/new Vector3(); - lengthSq: function () { + var _segDir = /*@__PURE__*/new Vector3(); - return this.x * this.x + this.y * this.y; + var _diff = /*@__PURE__*/new Vector3(); - }, + var _edge1 = /*@__PURE__*/new Vector3(); - length: function () { + var _edge2 = /*@__PURE__*/new Vector3(); - return Math.sqrt( this.x * this.x + this.y * this.y ); + var _normal = /*@__PURE__*/new Vector3(); - }, + var Ray = /*#__PURE__*/function () { + function Ray(origin, direction) { + this.origin = origin !== undefined ? origin : new Vector3(); + this.direction = direction !== undefined ? direction : new Vector3(0, 0, -1); + } - normalize: function () { + var _proto = Ray.prototype; - return this.divideScalar( this.length() ); + _proto.set = function set(origin, direction) { + this.origin.copy(origin); + this.direction.copy(direction); + return this; + }; - }, + _proto.clone = function clone() { + return new this.constructor().copy(this); + }; - distanceTo: function ( v ) { + _proto.copy = function copy(ray) { + this.origin.copy(ray.origin); + this.direction.copy(ray.direction); + return this; + }; - return Math.sqrt( this.distanceToSquared( v ) ); + _proto.at = function at(t, target) { + if (target === undefined) { + console.warn('THREE.Ray: .at() target is now required'); + target = new Vector3(); + } - }, + return target.copy(this.direction).multiplyScalar(t).add(this.origin); + }; - distanceToSquared: function ( v ) { + _proto.lookAt = function lookAt(v) { + this.direction.copy(v).sub(this.origin).normalize(); + return this; + }; - var dx = this.x - v.x, dy = this.y - v.y; - return dx * dx + dy * dy; + _proto.recast = function recast(t) { + this.origin.copy(this.at(t, _vector$2)); + return this; + }; - }, + _proto.closestPointToPoint = function closestPointToPoint(point, target) { + if (target === undefined) { + console.warn('THREE.Ray: .closestPointToPoint() target is now required'); + target = new Vector3(); + } - setLength: function ( l ) { + target.subVectors(point, this.origin); + var directionDistance = target.dot(this.direction); - var oldLength = this.length(); + if (directionDistance < 0) { + return target.copy(this.origin); + } - if ( oldLength !== 0 && l !== oldLength ) { + return target.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); + }; - this.multiplyScalar( l / oldLength ); - } + _proto.distanceToPoint = function distanceToPoint(point) { + return Math.sqrt(this.distanceSqToPoint(point)); + }; - return this; + _proto.distanceSqToPoint = function distanceSqToPoint(point) { + var directionDistance = _vector$2.subVectors(point, this.origin).dot(this.direction); // point behind the ray - }, - lerp: function ( v, alpha ) { + if (directionDistance < 0) { + return this.origin.distanceToSquared(point); + } - this.x += ( v.x - this.x ) * alpha; - this.y += ( v.y - this.y ) * alpha; + _vector$2.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); - return this; + return _vector$2.distanceToSquared(point); + }; - }, + _proto.distanceSqToSegment = function distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) { + // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h + // It returns the min distance between the ray and the segment + // defined by v0 and v1 + // It can also set two optional targets : + // - The closest point on the ray + // - The closest point on the segment + _segCenter.copy(v0).add(v1).multiplyScalar(0.5); - equals: function( v ) { + _segDir.copy(v1).sub(v0).normalize(); - return ( ( v.x === this.x ) && ( v.y === this.y ) ); + _diff.copy(this.origin).sub(_segCenter); - }, + var segExtent = v0.distanceTo(v1) * 0.5; + var a01 = -this.direction.dot(_segDir); - fromArray: function ( array ) { + var b0 = _diff.dot(this.direction); - this.x = array[ 0 ]; - this.y = array[ 1 ]; + var b1 = -_diff.dot(_segDir); - return this; + var c = _diff.lengthSq(); - }, + var det = Math.abs(1 - a01 * a01); + var s0, s1, sqrDist, extDet; - toArray: function () { + if (det > 0) { + // The ray and segment are not parallel. + s0 = a01 * b1 - b0; + s1 = a01 * b0 - b1; + extDet = segExtent * det; - return [ this.x, this.y ]; + if (s0 >= 0) { + if (s1 >= -extDet) { + if (s1 <= extDet) { + // region 0 + // Minimum at interior points of ray and segment. + var invDet = 1 / det; + s0 *= invDet; + s1 *= invDet; + sqrDist = s0 * (s0 + a01 * s1 + 2 * b0) + s1 * (a01 * s0 + s1 + 2 * b1) + c; + } else { + // region 1 + s1 = segExtent; + s0 = Math.max(0, -(a01 * s1 + b0)); + sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; + } + } else { + // region 5 + s1 = -segExtent; + s0 = Math.max(0, -(a01 * s1 + b0)); + sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; + } + } else { + if (s1 <= -extDet) { + // region 4 + s0 = Math.max(0, -(-a01 * segExtent + b0)); + s1 = s0 > 0 ? -segExtent : Math.min(Math.max(-segExtent, -b1), segExtent); + sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; + } else if (s1 <= extDet) { + // region 3 + s0 = 0; + s1 = Math.min(Math.max(-segExtent, -b1), segExtent); + sqrDist = s1 * (s1 + 2 * b1) + c; + } else { + // region 2 + s0 = Math.max(0, -(a01 * segExtent + b0)); + s1 = s0 > 0 ? segExtent : Math.min(Math.max(-segExtent, -b1), segExtent); + sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; + } + } + } else { + // Ray and segment are parallel. + s1 = a01 > 0 ? -segExtent : segExtent; + s0 = Math.max(0, -(a01 * s1 + b0)); + sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c; + } - }, + if (optionalPointOnRay) { + optionalPointOnRay.copy(this.direction).multiplyScalar(s0).add(this.origin); + } - clone: function () { + if (optionalPointOnSegment) { + optionalPointOnSegment.copy(_segDir).multiplyScalar(s1).add(_segCenter); + } - return new THREE.Vector2( this.x, this.y ); + return sqrDist; + }; - } + _proto.intersectSphere = function intersectSphere(sphere, target) { + _vector$2.subVectors(sphere.center, this.origin); -}; + var tca = _vector$2.dot(this.direction); -/** - * @author mrdoob / http://mrdoob.com/ - * @author *kile / http://kile.stravaganza.org/ - * @author philogb / http://blog.thejit.org/ - * @author mikael emtinger / http://gomo.se/ - * @author egraether / http://egraether.com/ - * @author WestLangley / http://github.com/WestLangley - */ + var d2 = _vector$2.dot(_vector$2) - tca * tca; + var radius2 = sphere.radius * sphere.radius; + if (d2 > radius2) return null; + var thc = Math.sqrt(radius2 - d2); // t0 = first intersect point - entrance on front of sphere -THREE.Vector3 = function ( x, y, z ) { + var t0 = tca - thc; // t1 = second intersect point - exit point on back of sphere - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; + var t1 = tca + thc; // test to see if both t0 and t1 are behind the ray - if so, return null -}; + if (t0 < 0 && t1 < 0) return null; // test to see if t0 is behind the ray: + // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, + // in order to always return an intersect point that is in front of the ray. -THREE.Vector3.prototype = { + if (t0 < 0) return this.at(t1, target); // else t0 is in front of the ray, so return the first collision point scaled by t0 - constructor: THREE.Vector3, + return this.at(t0, target); + }; - set: function ( x, y, z ) { + _proto.intersectsSphere = function intersectsSphere(sphere) { + return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius; + }; - this.x = x; - this.y = y; - this.z = z; + _proto.distanceToPlane = function distanceToPlane(plane) { + var denominator = plane.normal.dot(this.direction); - return this; + if (denominator === 0) { + // line is coplanar, return origin + if (plane.distanceToPoint(this.origin) === 0) { + return 0; + } // Null is preferable to undefined since undefined means.... it is undefined - }, - setX: function ( x ) { + return null; + } - this.x = x; + var t = -(this.origin.dot(plane.normal) + plane.constant) / denominator; // Return if the ray never intersects the plane - return this; + return t >= 0 ? t : null; + }; - }, + _proto.intersectPlane = function intersectPlane(plane, target) { + var t = this.distanceToPlane(plane); - setY: function ( y ) { + if (t === null) { + return null; + } - this.y = y; + return this.at(t, target); + }; - return this; + _proto.intersectsPlane = function intersectsPlane(plane) { + // check if the ray lies on the plane first + var distToPoint = plane.distanceToPoint(this.origin); - }, + if (distToPoint === 0) { + return true; + } - setZ: function ( z ) { + var denominator = plane.normal.dot(this.direction); - this.z = z; + if (denominator * distToPoint < 0) { + return true; + } // ray origin is behind the plane (and is pointing behind it) - return this; - }, + return false; + }; - setComponent: function ( index, value ) { + _proto.intersectBox = function intersectBox(box, target) { + var tmin, tmax, tymin, tymax, tzmin, tzmax; + var invdirx = 1 / this.direction.x, + invdiry = 1 / this.direction.y, + invdirz = 1 / this.direction.z; + var origin = this.origin; - switch ( index ) { + if (invdirx >= 0) { + tmin = (box.min.x - origin.x) * invdirx; + tmax = (box.max.x - origin.x) * invdirx; + } else { + tmin = (box.max.x - origin.x) * invdirx; + tmax = (box.min.x - origin.x) * invdirx; + } - 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 ); + if (invdiry >= 0) { + tymin = (box.min.y - origin.y) * invdiry; + tymax = (box.max.y - origin.y) * invdiry; + } else { + tymin = (box.max.y - origin.y) * invdiry; + tymax = (box.min.y - origin.y) * invdiry; + } - } + if (tmin > tymax || tymin > tmax) return null; // These lines also handle the case where tmin or tmax is NaN + // (result of 0 * Infinity). x !== x returns true if x is NaN - }, + if (tymin > tmin || tmin !== tmin) tmin = tymin; + if (tymax < tmax || tmax !== tmax) tmax = tymax; - getComponent: function ( index ) { + if (invdirz >= 0) { + tzmin = (box.min.z - origin.z) * invdirz; + tzmax = (box.max.z - origin.z) * invdirz; + } else { + tzmin = (box.max.z - origin.z) * invdirz; + tzmax = (box.min.z - origin.z) * invdirz; + } - switch ( index ) { + if (tmin > tzmax || tzmin > tmax) return null; + if (tzmin > tmin || tmin !== tmin) tmin = tzmin; + if (tzmax < tmax || tmax !== tmax) tmax = tzmax; //return point closest to the ray (positive side) - 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 ); + if (tmax < 0) return null; + return this.at(tmin >= 0 ? tmin : tmax, target); + }; - } + _proto.intersectsBox = function intersectsBox(box) { + return this.intersectBox(box, _vector$2) !== null; + }; - }, + _proto.intersectTriangle = function intersectTriangle(a, b, c, backfaceCulling, target) { + // Compute the offset origin, edges, and normal. + // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h + _edge1.subVectors(b, a); - copy: function ( v ) { + _edge2.subVectors(c, a); - this.x = v.x; - this.y = v.y; - this.z = v.z; + _normal.crossVectors(_edge1, _edge2); // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, + // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by + // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) + // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) + // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) - return this; - }, + var DdN = this.direction.dot(_normal); + var sign; - add: function ( v, w ) { + if (DdN > 0) { + if (backfaceCulling) return null; + sign = 1; + } else if (DdN < 0) { + sign = -1; + DdN = -DdN; + } else { + return null; + } - if ( w !== undefined ) { + _diff.subVectors(this.origin, a); - console.warn( 'DEPRECATED: Vector3\'s .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); + var DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2)); // b1 < 0, no intersection - } + if (DdQxE2 < 0) { + return null; + } - this.x += v.x; - this.y += v.y; - this.z += v.z; + var DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff)); // b2 < 0, no intersection - return this; + if (DdE1xQ < 0) { + return null; + } // b1+b2 > 1, no intersection - }, - addScalar: function ( s ) { + if (DdQxE2 + DdE1xQ > DdN) { + return null; + } // Line intersects triangle, check if ray does. - this.x += s; - this.y += s; - this.z += s; - return this; + var QdN = -sign * _diff.dot(_normal); // t < 0, no intersection - }, - addVectors: function ( a, b ) { + if (QdN < 0) { + return null; + } // Ray intersects triangle. - this.x = a.x + b.x; - this.y = a.y + b.y; - this.z = a.z + b.z; - return this; + return this.at(QdN / DdN, target); + }; - }, + _proto.applyMatrix4 = function applyMatrix4(matrix4) { + this.origin.applyMatrix4(matrix4); + this.direction.transformDirection(matrix4); + return this; + }; - sub: function ( v, w ) { + _proto.equals = function equals(ray) { + return ray.origin.equals(this.origin) && ray.direction.equals(this.direction); + }; - if ( w !== undefined ) { + return Ray; + }(); - console.warn( 'DEPRECATED: Vector3\'s .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); + var Matrix4 = /*#__PURE__*/function () { + function Matrix4() { + Object.defineProperty(this, 'isMatrix4', { + value: true + }); + 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.'); + } } - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; + var _proto = Matrix4.prototype; - return this; + _proto.set = function set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) { + var 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; + }; - }, + _proto.identity = function identity() { + this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + return this; + }; - subVectors: function ( a, b ) { + _proto.clone = function clone() { + return new Matrix4().fromArray(this.elements); + }; - this.x = a.x - b.x; - this.y = a.y - b.y; - this.z = a.z - b.z; + _proto.copy = function copy(m) { + var te = this.elements; + var 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; + }; - return this; + _proto.copyPosition = function copyPosition(m) { + var te = this.elements, + me = m.elements; + te[12] = me[12]; + te[13] = me[13]; + te[14] = me[14]; + return this; + }; - }, + _proto.extractBasis = function extractBasis(xAxis, yAxis, zAxis) { + xAxis.setFromMatrixColumn(this, 0); + yAxis.setFromMatrixColumn(this, 1); + zAxis.setFromMatrixColumn(this, 2); + return this; + }; - multiply: function ( v, w ) { + _proto.makeBasis = function 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; + }; - if ( w !== undefined ) { + _proto.extractRotation = function extractRotation(m) { + // this method does not support reflection matrices + var te = this.elements; + var me = m.elements; - console.warn( 'DEPRECATED: Vector3\'s .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); - return this.multiplyVectors( v, w ); + var scaleX = 1 / _v1$1.setFromMatrixColumn(m, 0).length(); - } + var scaleY = 1 / _v1$1.setFromMatrixColumn(m, 1).length(); - this.x *= v.x; - this.y *= v.y; - this.z *= v.z; + var scaleZ = 1 / _v1$1.setFromMatrixColumn(m, 2).length(); - return this; + 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; + }; - }, + _proto.makeRotationFromEuler = function makeRotationFromEuler(euler) { + if (!(euler && euler.isEuler)) { + console.error('THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.'); + } - multiplyScalar: function ( scalar ) { + var te = this.elements; + var x = euler.x, + y = euler.y, + z = euler.z; + var a = Math.cos(x), + b = Math.sin(x); + var c = Math.cos(y), + d = Math.sin(y); + var e = Math.cos(z), + f = Math.sin(z); + + if (euler.order === 'XYZ') { + var 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') { + var 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') { + var _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') { + var _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') { + var 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') { + var _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; + }; - this.x *= scalar; - this.y *= scalar; - this.z *= scalar; + _proto.makeRotationFromQuaternion = function makeRotationFromQuaternion(q) { + return this.compose(_zero, q, _one); + }; - return this; + _proto.lookAt = function lookAt(eye, target, up) { + var te = this.elements; - }, + _z.subVectors(eye, target); - multiplyVectors: function ( a, b ) { + if (_z.lengthSq() === 0) { + // eye and target are in the same position + _z.z = 1; + } - this.x = a.x * b.x; - this.y = a.y * b.y; - this.z = a.z * b.z; + _z.normalize(); - return this; + _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; + } - applyEuler: function () { + _z.normalize(); - var quaternion; + _x.crossVectors(up, _z); + } - return function ( euler ) { + _x.normalize(); - if ( euler instanceof THREE.Euler === false ) { + _y.crossVectors(_z, _x); - console.error( 'ERROR: Vector3\'s .applyEuler() now expects a Euler rotation rather than a Vector3 and order. Please update your code.' ); + 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; + }; + _proto.multiply = function 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); } - if ( quaternion === undefined ) quaternion = new THREE.Quaternion(); + return this.multiplyMatrices(this, m); + }; - this.applyQuaternion( quaternion.setFromEuler( euler ) ); + _proto.premultiply = function premultiply(m) { + return this.multiplyMatrices(m, this); + }; + _proto.multiplyMatrices = function multiplyMatrices(a, b) { + var ae = a.elements; + var be = b.elements; + var te = this.elements; + var a11 = ae[0], + a12 = ae[4], + a13 = ae[8], + a14 = ae[12]; + var a21 = ae[1], + a22 = ae[5], + a23 = ae[9], + a24 = ae[13]; + var a31 = ae[2], + a32 = ae[6], + a33 = ae[10], + a34 = ae[14]; + var a41 = ae[3], + a42 = ae[7], + a43 = ae[11], + a44 = ae[15]; + var b11 = be[0], + b12 = be[4], + b13 = be[8], + b14 = be[12]; + var b21 = be[1], + b22 = be[5], + b23 = be[9], + b24 = be[13]; + var b31 = be[2], + b32 = be[6], + b33 = be[10], + b34 = be[14]; + var 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; - }; - }(), - - applyAxisAngle: function () { + _proto.multiplyScalar = function multiplyScalar(s) { + var 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; + }; - var quaternion; + _proto.determinant = function determinant() { + var te = this.elements; + var n11 = te[0], + n12 = te[4], + n13 = te[8], + n14 = te[12]; + var n21 = te[1], + n22 = te[5], + n23 = te[9], + n24 = te[13]; + var n31 = te[2], + n32 = te[6], + n33 = te[10], + n34 = te[14]; + var 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); + }; - return function ( axis, angle ) { + _proto.transpose = function transpose() { + var te = this.elements; + var 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; + }; - if ( quaternion === undefined ) quaternion = new THREE.Quaternion(); + _proto.setPosition = function setPosition(x, y, z) { + var te = this.elements; - this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) ); + 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; + }; + _proto.getInverse = function getInverse(m, throwOnDegenerate) { + if (throwOnDegenerate !== undefined) { + console.warn("THREE.Matrix4: .getInverse() can no longer be configured to throw on degenerate."); + } // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm + + + var te = this.elements, + me = m.elements, + n11 = me[0], + n21 = me[1], + n31 = me[2], + n41 = me[3], + n12 = me[4], + n22 = me[5], + n32 = me[6], + n42 = me[7], + n13 = me[8], + n23 = me[9], + n33 = me[10], + n43 = me[11], + n14 = me[12], + n24 = me[13], + n34 = me[14], + n44 = me[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; + var 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); + var 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; }; - }(), + _proto.scale = function scale(v) { + var te = this.elements; + var 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; + }; - applyMatrix3: function ( m ) { + _proto.getMaxScaleOnAxis = function getMaxScaleOnAxis() { + var te = this.elements; + var scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2]; + var scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6]; + var scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10]; + return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq)); + }; - var x = this.x; - var y = this.y; - var z = this.z; + _proto.makeTranslation = function makeTranslation(x, y, z) { + this.set(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1); + return this; + }; - var e = m.elements; + _proto.makeRotationX = function makeRotationX(theta) { + var 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; + }; - 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; + _proto.makeRotationY = function makeRotationY(theta) { + var 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; + }; - return this; + _proto.makeRotationZ = function makeRotationZ(theta) { + var 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; + }; - }, + _proto.makeRotationAxis = function makeRotationAxis(axis, angle) { + // Based on http://www.gamedev.net/reference/articles/article1199.asp + var c = Math.cos(angle); + var s = Math.sin(angle); + var t = 1 - c; + var x = axis.x, + y = axis.y, + z = axis.z; + var 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; + }; - applyMatrix4: function ( m ) { + _proto.makeScale = function makeScale(x, y, z) { + this.set(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1); + return this; + }; - // input: THREE.Matrix4 affine matrix + _proto.makeShear = function makeShear(x, y, z) { + this.set(1, y, z, 0, x, 1, z, 0, x, y, 1, 0, 0, 0, 0, 1); + return this; + }; - var x = this.x, y = this.y, z = this.z; + _proto.compose = function compose(position, quaternion, scale) { + var te = this.elements; + var x = quaternion._x, + y = quaternion._y, + z = quaternion._z, + w = quaternion._w; + var x2 = x + x, + y2 = y + y, + z2 = z + z; + var xx = x * x2, + xy = x * y2, + xz = x * z2; + var yy = y * y2, + yz = y * z2, + zz = z * z2; + var wx = w * x2, + wy = w * y2, + wz = w * z2; + var sx = scale.x, + sy = scale.y, + sz = scale.z; + 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; + }; - var e = m.elements; + _proto.decompose = function decompose(position, quaternion, scale) { + var te = this.elements; - this.x = e[0] * x + e[4] * y + e[8] * z + e[12]; - this.y = e[1] * x + e[5] * y + e[9] * z + e[13]; - this.z = e[2] * x + e[6] * y + e[10] * z + e[14]; + var sx = _v1$1.set(te[0], te[1], te[2]).length(); - return this; + var sy = _v1$1.set(te[4], te[5], te[6]).length(); - }, + var sz = _v1$1.set(te[8], te[9], te[10]).length(); // if determine is negative, we need to invert one scale - applyProjection: function ( m ) { - // input: THREE.Matrix4 projection matrix + var det = this.determinant(); + if (det < 0) sx = -sx; + position.x = te[12]; + position.y = te[13]; + position.z = te[14]; // scale the rotation part - var x = this.x, y = this.y, z = this.z; + _m1.copy(this); - var e = m.elements; - var d = 1 / ( e[3] * x + e[7] * y + e[11] * z + e[15] ); // perspective divide + var invSX = 1 / sx; + var invSY = 1 / sy; + var 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; + }; - this.x = ( e[0] * x + e[4] * y + e[8] * z + e[12] ) * d; - this.y = ( e[1] * x + e[5] * y + e[9] * z + e[13] ) * d; - this.z = ( e[2] * x + e[6] * y + e[10] * z + e[14] ) * d; + _proto.makePerspective = function 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.'); + } - return this; + var te = this.elements; + var x = 2 * near / (right - left); + var y = 2 * near / (top - bottom); + var a = (right + left) / (right - left); + var b = (top + bottom) / (top - bottom); + var c = -(far + near) / (far - near); + var 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; + }; - }, + _proto.makeOrthographic = function makeOrthographic(left, right, top, bottom, near, far) { + var te = this.elements; + var w = 1.0 / (right - left); + var h = 1.0 / (top - bottom); + var p = 1.0 / (far - near); + var x = (right + left) * w; + var y = (top + bottom) * h; + var 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; + }; - applyQuaternion: function ( q ) { + _proto.equals = function equals(matrix) { + var te = this.elements; + var me = matrix.elements; - var x = this.x; - var y = this.y; - var z = this.z; + for (var i = 0; i < 16; i++) { + if (te[i] !== me[i]) return false; + } - var qx = q.x; - var qy = q.y; - var qz = q.z; - var qw = q.w; + return true; + }; - // calculate quat * vector + _proto.fromArray = function fromArray(array, offset) { + if (offset === void 0) { + offset = 0; + } - var ix = qw * x + qy * z - qz * y; - var iy = qw * y + qz * x - qx * z; - var iz = qw * z + qx * y - qy * x; - var iw = -qx * x - qy * y - qz * z; + for (var i = 0; i < 16; i++) { + this.elements[i] = array[i + offset]; + } - // calculate result * inverse quat + return this; + }; - 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; + _proto.toArray = function toArray(array, offset) { + if (array === void 0) { + array = []; + } - return this; + if (offset === void 0) { + offset = 0; + } - }, + var 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; + }; - transformDirection: function ( m ) { + return Matrix4; + }(); - // input: THREE.Matrix4 affine matrix - // vector interpreted as a direction + var _v1$1 = /*@__PURE__*/new Vector3(); - var x = this.x, y = this.y, z = this.z; + var _m1 = /*@__PURE__*/new Matrix4(); - var e = m.elements; + var _zero = /*@__PURE__*/new Vector3(0, 0, 0); - 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; + var _one = /*@__PURE__*/new Vector3(1, 1, 1); - this.normalize(); + var _x = /*@__PURE__*/new Vector3(); - return this; + var _y = /*@__PURE__*/new Vector3(); - }, + var _z = /*@__PURE__*/new Vector3(); - divide: function ( v ) { + var Euler = /*#__PURE__*/function () { + function Euler(x, y, z, order) { + if (x === void 0) { + x = 0; + } - this.x /= v.x; - this.y /= v.y; - this.z /= v.z; + if (y === void 0) { + y = 0; + } - return this; + if (z === void 0) { + z = 0; + } - }, + if (order === void 0) { + order = Euler.DefaultOrder; + } - divideScalar: function ( scalar ) { + Object.defineProperty(this, 'isEuler', { + value: true + }); + this._x = x; + this._y = y; + this._z = z; + this._order = order; + } - if ( scalar !== 0 ) { + var _proto = Euler.prototype; - var invScalar = 1 / scalar; + _proto.set = function set(x, y, z, order) { + this._x = x; + this._y = y; + this._z = z; + this._order = order || this._order; - this.x *= invScalar; - this.y *= invScalar; - this.z *= invScalar; + this._onChangeCallback(); - } else { + return this; + }; - this.x = 0; - this.y = 0; - this.z = 0; + _proto.clone = function clone() { + return new this.constructor(this._x, this._y, this._z, this._order); + }; - } + _proto.copy = function copy(euler) { + this._x = euler._x; + this._y = euler._y; + this._z = euler._z; + this._order = euler._order; - return this; + this._onChangeCallback(); - }, + return this; + }; - min: function ( v ) { + _proto.setFromRotationMatrix = function setFromRotationMatrix(m, order, update) { + var clamp = MathUtils.clamp; // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + + var te = m.elements; + var m11 = te[0], + m12 = te[4], + m13 = te[8]; + var m21 = te[1], + m22 = te[5], + m23 = te[9]; + var m31 = te[2], + m32 = te[6], + m33 = te[10]; + order = order || this._order; + + 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; + } - if ( this.x > v.x ) { + break; - this.x = v.x; + 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; + } - if ( this.y > v.y ) { + break; - this.y = v.y; + 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); + } - if ( this.z > v.z ) { + break; - this.z = v.z; + 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); + } - return this; + break; - }, + case 'YZX': + this._z = Math.asin(clamp(m21, -1, 1)); - max: function ( v ) { + 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); + } - if ( this.x < v.x ) { + break; - this.x = v.x; + 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; + } - if ( this.y < v.y ) { + break; - this.y = v.y; + default: + console.warn('THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order); + } - } + this._order = order; + if (update !== false) this._onChangeCallback(); + return this; + }; - if ( this.z < v.z ) { + _proto.setFromQuaternion = function setFromQuaternion(q, order, update) { + _matrix.makeRotationFromQuaternion(q); - this.z = v.z; + return this.setFromRotationMatrix(_matrix, order, update); + }; - } + _proto.setFromVector3 = function setFromVector3(v, order) { + return this.set(v.x, v.y, v.z, order || this._order); + }; - return this; + _proto.reorder = function reorder(newOrder) { + // WARNING: this discards revolution information -bhouston + _quaternion$1.setFromEuler(this); - }, + return this.setFromQuaternion(_quaternion$1, newOrder); + }; - clamp: function ( min, max ) { + _proto.equals = function equals(euler) { + return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order; + }; - // This function assumes min < max, if this assumption isn't true it will not operate correctly + _proto.fromArray = function fromArray(array) { + this._x = array[0]; + this._y = array[1]; + this._z = array[2]; + if (array[3] !== undefined) this._order = array[3]; - if ( this.x < min.x ) { + this._onChangeCallback(); - this.x = min.x; + return this; + }; - } else if ( this.x > max.x ) { + _proto.toArray = function toArray(array, offset) { + if (array === void 0) { + array = []; + } - this.x = max.x; + if (offset === void 0) { + offset = 0; + } - } + array[offset] = this._x; + array[offset + 1] = this._y; + array[offset + 2] = this._z; + array[offset + 3] = this._order; + return array; + }; - if ( this.y < min.y ) { + _proto.toVector3 = function toVector3(optionalResult) { + if (optionalResult) { + return optionalResult.set(this._x, this._y, this._z); + } else { + return new Vector3(this._x, this._y, this._z); + } + }; - this.y = min.y; + _proto._onChange = function _onChange(callback) { + this._onChangeCallback = callback; + return this; + }; - } else if ( this.y > max.y ) { + _proto._onChangeCallback = function _onChangeCallback() {}; - this.y = max.y; + _createClass(Euler, [{ + key: "x", + get: function get() { + return this._x; + }, + set: function set(value) { + this._x = value; - } + this._onChangeCallback(); + } + }, { + key: "y", + get: function get() { + return this._y; + }, + set: function set(value) { + this._y = value; - if ( this.z < min.z ) { + this._onChangeCallback(); + } + }, { + key: "z", + get: function get() { + return this._z; + }, + set: function set(value) { + this._z = value; - this.z = min.z; + this._onChangeCallback(); + } + }, { + key: "order", + get: function get() { + return this._order; + }, + set: function set(value) { + this._order = value; - } else if ( this.z > max.z ) { + this._onChangeCallback(); + } + }]); - this.z = max.z; + return Euler; + }(); - } + Euler.DefaultOrder = 'XYZ'; + Euler.RotationOrders = ['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX']; - return this; + var _matrix = /*@__PURE__*/new Matrix4(); - }, + var _quaternion$1 = /*@__PURE__*/new Quaternion(); - clampScalar: ( function () { + var Layers = /*#__PURE__*/function () { + function Layers() { + this.mask = 1 | 0; + } - var min, max; + var _proto = Layers.prototype; - return function ( minVal, maxVal ) { + _proto.set = function set(channel) { + this.mask = 1 << channel | 0; + }; - if ( min === undefined ) { + _proto.enable = function enable(channel) { + this.mask |= 1 << channel | 0; + }; - min = new THREE.Vector3(); - max = new THREE.Vector3(); + _proto.enableAll = function enableAll() { + this.mask = 0xffffffff | 0; + }; - } + _proto.toggle = function toggle(channel) { + this.mask ^= 1 << channel | 0; + }; - min.set( minVal, minVal, minVal ); - max.set( maxVal, maxVal, maxVal ); + _proto.disable = function disable(channel) { + this.mask &= ~(1 << channel | 0); + }; - return this.clamp( min, max ); + _proto.disableAll = function disableAll() { + this.mask = 0; + }; + _proto.test = function test(layers) { + return (this.mask & layers.mask) !== 0; }; - } )(), + return Layers; + }(); - floor: function () { + var _object3DId = 0; - this.x = Math.floor( this.x ); - this.y = Math.floor( this.y ); - this.z = Math.floor( this.z ); + var _v1$2 = new Vector3(); - return this; + var _q1 = new Quaternion(); - }, + var _m1$1 = new Matrix4(); - ceil: function () { + var _target = new Vector3(); - this.x = Math.ceil( this.x ); - this.y = Math.ceil( this.y ); - this.z = Math.ceil( this.z ); + var _position = new Vector3(); - return this; + var _scale = new Vector3(); - }, + var _quaternion$2 = new Quaternion(); - round: function () { + var _xAxis = new Vector3(1, 0, 0); - this.x = Math.round( this.x ); - this.y = Math.round( this.y ); - this.z = Math.round( this.z ); + var _yAxis = new Vector3(0, 1, 0); - return this; + var _zAxis = new Vector3(0, 0, 1); - }, + var _addedEvent = { + type: 'added' + }; + var _removedEvent = { + type: 'removed' + }; - roundToZero: function () { + function Object3D() { + Object.defineProperty(this, 'id', { + value: _object3DId++ + }); + this.uuid = MathUtils.generateUUID(); + this.name = ''; + this.type = 'Object3D'; + this.parent = null; + this.children = []; + this.up = Object3D.DefaultUp.clone(); + var position = new Vector3(); + var rotation = new Euler(); + var quaternion = new Quaternion(); + var 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.userData = {}; + } + + Object3D.DefaultUp = new Vector3(0, 1, 0); + Object3D.DefaultMatrixAutoUpdate = true; + Object3D.prototype = Object.assign(Object.create(EventDispatcher.prototype), { + constructor: Object3D, + isObject3D: true, + onBeforeRender: function onBeforeRender() {}, + onAfterRender: function onAfterRender() {}, + applyMatrix4: function applyMatrix4(matrix) { + if (this.matrixAutoUpdate) this.updateMatrix(); + this.matrix.premultiply(matrix); + this.matrix.decompose(this.position, this.quaternion, this.scale); + }, + applyQuaternion: function applyQuaternion(q) { + this.quaternion.premultiply(q); + return this; + }, + setRotationFromAxisAngle: function setRotationFromAxisAngle(axis, angle) { + // assumes axis is normalized + this.quaternion.setFromAxisAngle(axis, angle); + }, + setRotationFromEuler: function setRotationFromEuler(euler) { + this.quaternion.setFromEuler(euler, true); + }, + setRotationFromMatrix: function setRotationFromMatrix(m) { + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + this.quaternion.setFromRotationMatrix(m); + }, + setRotationFromQuaternion: function setRotationFromQuaternion(q) { + // assumes q is normalized + this.quaternion.copy(q); + }, + rotateOnAxis: function rotateOnAxis(axis, angle) { + // rotate object on axis in object space + // axis is assumed to be normalized + _q1.setFromAxisAngle(axis, angle); - 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.quaternion.multiply(_q1); + return this; + }, + rotateOnWorldAxis: function 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); - return this; + this.quaternion.premultiply(_q1); + return this; + }, + rotateX: function rotateX(angle) { + return this.rotateOnAxis(_xAxis, angle); + }, + rotateY: function rotateY(angle) { + return this.rotateOnAxis(_yAxis, angle); + }, + rotateZ: function rotateZ(angle) { + return this.rotateOnAxis(_zAxis, angle); + }, + translateOnAxis: function translateOnAxis(axis, distance) { + // translate object by distance along axis in object space + // axis is assumed to be normalized + _v1$2.copy(axis).applyQuaternion(this.quaternion); - }, + this.position.add(_v1$2.multiplyScalar(distance)); + return this; + }, + translateX: function translateX(distance) { + return this.translateOnAxis(_xAxis, distance); + }, + translateY: function translateY(distance) { + return this.translateOnAxis(_yAxis, distance); + }, + translateZ: function translateZ(distance) { + return this.translateOnAxis(_zAxis, distance); + }, + localToWorld: function localToWorld(vector) { + return vector.applyMatrix4(this.matrixWorld); + }, + worldToLocal: function worldToLocal(vector) { + return vector.applyMatrix4(_m1$1.getInverse(this.matrixWorld)); + }, + lookAt: function 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); + } - negate: function () { + var parent = this.parent; + this.updateWorldMatrix(true, false); - return this.multiplyScalar( - 1 ); + _position.setFromMatrixPosition(this.matrixWorld); - }, + if (this.isCamera || this.isLight) { + _m1$1.lookAt(_position, _target, this.up); + } else { + _m1$1.lookAt(_target, _position, this.up); + } - dot: function ( v ) { + this.quaternion.setFromRotationMatrix(_m1$1); - return this.x * v.x + this.y * v.y + this.z * v.z; + if (parent) { + _m1$1.extractRotation(parent.matrixWorld); - }, + _q1.setFromRotationMatrix(_m1$1); - lengthSq: function () { + this.quaternion.premultiply(_q1.inverse()); + } + }, + add: function add(object) { + if (arguments.length > 1) { + for (var i = 0; i < arguments.length; i++) { + this.add(arguments[i]); + } - return this.x * this.x + this.y * this.y + this.z * this.z; + return this; + } - }, + if (object === this) { + console.error("THREE.Object3D.add: object can't be added as a child of itself.", object); + return this; + } - length: function () { + if (object && object.isObject3D) { + if (object.parent !== null) { + object.parent.remove(object); + } - return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); + 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: function remove(object) { + if (arguments.length > 1) { + for (var i = 0; i < arguments.length; i++) { + this.remove(arguments[i]); + } - lengthManhattan: function () { + return this; + } - return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); + var index = this.children.indexOf(object); - }, + if (index !== -1) { + object.parent = null; + this.children.splice(index, 1); + object.dispatchEvent(_removedEvent); + } - normalize: function () { + return this; + }, + clear: function clear() { + for (var i = 0; i < this.children.length; i++) { + var object = this.children[i]; + object.parent = null; + object.dispatchEvent(_removedEvent); + } - return this.divideScalar( this.length() ); + this.children.length = 0; + return this; + }, + attach: function attach(object) { + // adds object as a child of this, while maintaining the object's world transform + this.updateWorldMatrix(true, false); - }, + _m1$1.getInverse(this.matrixWorld); - setLength: function ( l ) { + if (object.parent !== null) { + object.parent.updateWorldMatrix(true, false); - var oldLength = this.length(); + _m1$1.multiply(object.parent.matrixWorld); + } - if ( oldLength !== 0 && l !== oldLength ) { + object.applyMatrix4(_m1$1); + object.updateWorldMatrix(false, false); + this.add(object); + return this; + }, + getObjectById: function getObjectById(id) { + return this.getObjectByProperty('id', id); + }, + getObjectByName: function getObjectByName(name) { + return this.getObjectByProperty('name', name); + }, + getObjectByProperty: function getObjectByProperty(name, value) { + if (this[name] === value) return this; - this.multiplyScalar( l / oldLength ); - } + for (var i = 0, l = this.children.length; i < l; i++) { + var child = this.children[i]; + var object = child.getObjectByProperty(name, value); - return this; + if (object !== undefined) { + return object; + } + } - }, + return undefined; + }, + getWorldPosition: function getWorldPosition(target) { + if (target === undefined) { + console.warn('THREE.Object3D: .getWorldPosition() target is now required'); + target = new Vector3(); + } - lerp: function ( v, alpha ) { + this.updateWorldMatrix(true, false); + return target.setFromMatrixPosition(this.matrixWorld); + }, + getWorldQuaternion: function getWorldQuaternion(target) { + if (target === undefined) { + console.warn('THREE.Object3D: .getWorldQuaternion() target is now required'); + target = new Quaternion(); + } - this.x += ( v.x - this.x ) * alpha; - this.y += ( v.y - this.y ) * alpha; - this.z += ( v.z - this.z ) * alpha; + this.updateWorldMatrix(true, false); + this.matrixWorld.decompose(_position, target, _scale); + return target; + }, + getWorldScale: function getWorldScale(target) { + if (target === undefined) { + console.warn('THREE.Object3D: .getWorldScale() target is now required'); + target = new Vector3(); + } - return this; + this.updateWorldMatrix(true, false); + this.matrixWorld.decompose(_position, _quaternion$2, target); + return target; + }, + getWorldDirection: function getWorldDirection(target) { + if (target === undefined) { + console.warn('THREE.Object3D: .getWorldDirection() target is now required'); + target = new Vector3(); + } - }, + this.updateWorldMatrix(true, false); + var e = this.matrixWorld.elements; + return target.set(e[8], e[9], e[10]).normalize(); + }, + raycast: function raycast() {}, + traverse: function traverse(callback) { + callback(this); + var children = this.children; - cross: function ( v, w ) { + for (var i = 0, l = children.length; i < l; i++) { + children[i].traverse(callback); + } + }, + traverseVisible: function traverseVisible(callback) { + if (this.visible === false) return; + callback(this); + var children = this.children; - if ( w !== undefined ) { + for (var i = 0, l = children.length; i < l; i++) { + children[i].traverseVisible(callback); + } + }, + traverseAncestors: function traverseAncestors(callback) { + var parent = this.parent; - console.warn( 'DEPRECATED: Vector3\'s .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); - return this.crossVectors( v, w ); + if (parent !== null) { + callback(parent); + parent.traverseAncestors(callback); + } + }, + updateMatrix: function updateMatrix() { + this.matrix.compose(this.position, this.quaternion, this.scale); + this.matrixWorldNeedsUpdate = true; + }, + updateMatrixWorld: function 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); + } - var x = this.x, y = this.y, z = this.z; + this.matrixWorldNeedsUpdate = false; + force = true; + } // update children - this.x = y * v.z - z * v.y; - this.y = z * v.x - x * v.z; - this.z = x * v.y - y * v.x; - return this; + var children = this.children; - }, + for (var i = 0, l = children.length; i < l; i++) { + children[i].updateMatrixWorld(force); + } + }, + updateWorldMatrix: function updateWorldMatrix(updateParents, updateChildren) { + var parent = this.parent; - crossVectors: function ( a, b ) { + if (updateParents === true && parent !== null) { + parent.updateWorldMatrix(true, false); + } - var ax = a.x, ay = a.y, az = a.z; - var bx = b.x, by = b.y, bz = b.z; + if (this.matrixAutoUpdate) this.updateMatrix(); - this.x = ay * bz - az * by; - this.y = az * bx - ax * bz; - this.z = ax * by - ay * bx; + if (this.parent === null) { + this.matrixWorld.copy(this.matrix); + } else { + this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix); + } // update children - return this; - }, + if (updateChildren === true) { + var children = this.children; - projectOnVector: function () { + for (var i = 0, l = children.length; i < l; i++) { + children[i].updateWorldMatrix(false, true); + } + } + }, + toJSON: function toJSON(meta) { + // meta is a string when called from JSON.stringify + var isRootObject = meta === undefined || typeof meta === 'string'; + var 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: {} + }; + output.metadata = { + version: 4.5, + type: 'Object', + generator: 'Object3D.toJSON' + }; + } // standard Object3D serialization + + + var 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(); + } // + + + function serialize(library, element) { + if (library[element.uuid] === undefined) { + library[element.uuid] = element.toJSON(meta); + } - var v1, dot; + return element.uuid; + } - return function ( vector ) { + if (this.isMesh || this.isLine || this.isPoints) { + object.geometry = serialize(meta.geometries, this.geometry); + var parameters = this.geometry.parameters; - if ( v1 === undefined ) v1 = new THREE.Vector3(); + if (parameters !== undefined && parameters.shapes !== undefined) { + var shapes = parameters.shapes; - v1.copy( vector ).normalize(); + if (Array.isArray(shapes)) { + for (var i = 0, l = shapes.length; i < l; i++) { + var shape = shapes[i]; + serialize(meta.shapes, shape); + } + } else { + serialize(meta.shapes, shapes); + } + } + } - dot = this.dot( v1 ); + if (this.material !== undefined) { + if (Array.isArray(this.material)) { + var uuids = []; - return this.copy( v1 ).multiplyScalar( dot ); + for (var _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); + } + } // - }(), - projectOnPlane: function () { + if (this.children.length > 0) { + object.children = []; - var v1; + for (var _i2 = 0; _i2 < this.children.length; _i2++) { + object.children.push(this.children[_i2].toJSON(meta).object); + } + } - return function ( planeNormal ) { + if (isRootObject) { + var geometries = extractFromCache(meta.geometries); + var materials = extractFromCache(meta.materials); + var textures = extractFromCache(meta.textures); + var images = extractFromCache(meta.images); - if ( v1 === undefined ) v1 = new THREE.Vector3(); + var _shapes = extractFromCache(meta.shapes); - v1.copy( this ).projectOnVector( planeNormal ); + 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; + } - return this.sub( v1 ); + output.object = object; + return output; // extract data from the cache hash + // remove metadata on each item + // and return as array - } + function extractFromCache(cache) { + var values = []; - }(), + for (var key in cache) { + var data = cache[key]; + delete data.metadata; + values.push(data); + } - reflect: function () { + return values; + } + }, + clone: function clone(recursive) { + return new this.constructor().copy(this, recursive); + }, + copy: function copy(source, recursive) { + if (recursive === undefined) 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 (var i = 0; i < source.children.length; i++) { + var child = source.children[i]; + this.add(child.clone()); + } + } - // reflect incident vector off plane orthogonal to normal - // normal is assumed to have unit length + return this; + } + }); - var v1; + var _vector1 = /*@__PURE__*/new Vector3(); - return function ( normal ) { + var _vector2 = /*@__PURE__*/new Vector3(); - if ( v1 === undefined ) v1 = new THREE.Vector3(); + var _normalMatrix = /*@__PURE__*/new Matrix3(); - return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); + var Plane = /*#__PURE__*/function () { + function Plane(normal, constant) { + Object.defineProperty(this, 'isPlane', { + value: true + }); // normal is assumed to be normalized + this.normal = normal !== undefined ? normal : new Vector3(1, 0, 0); + this.constant = constant !== undefined ? constant : 0; } - }(), + var _proto = Plane.prototype; - angleTo: function ( v ) { + _proto.set = function set(normal, constant) { + this.normal.copy(normal); + this.constant = constant; + return this; + }; - var theta = this.dot( v ) / ( this.length() * v.length() ); + _proto.setComponents = function setComponents(x, y, z, w) { + this.normal.set(x, y, z); + this.constant = w; + return this; + }; - // clamp, to handle numerical problems + _proto.setFromNormalAndCoplanarPoint = function setFromNormalAndCoplanarPoint(normal, point) { + this.normal.copy(normal); + this.constant = -point.dot(this.normal); + return this; + }; - return Math.acos( THREE.Math.clamp( theta, -1, 1 ) ); + _proto.setFromCoplanarPoints = function setFromCoplanarPoints(a, b, c) { + var normal = _vector1.subVectors(c, b).cross(_vector2.subVectors(a, b)).normalize(); // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? - }, - distanceTo: function ( v ) { + this.setFromNormalAndCoplanarPoint(normal, a); + return this; + }; - return Math.sqrt( this.distanceToSquared( v ) ); + _proto.clone = function clone() { + return new this.constructor().copy(this); + }; - }, + _proto.copy = function copy(plane) { + this.normal.copy(plane.normal); + this.constant = plane.constant; + return this; + }; - distanceToSquared: function ( v ) { + _proto.normalize = function normalize() { + // Note: will lead to a divide by zero if the plane is invalid. + var inverseNormalLength = 1.0 / this.normal.length(); + this.normal.multiplyScalar(inverseNormalLength); + this.constant *= inverseNormalLength; + return this; + }; - var dx = this.x - v.x; - var dy = this.y - v.y; - var dz = this.z - v.z; + _proto.negate = function negate() { + this.constant *= -1; + this.normal.negate(); + return this; + }; - return dx * dx + dy * dy + dz * dz; + _proto.distanceToPoint = function distanceToPoint(point) { + return this.normal.dot(point) + this.constant; + }; - }, + _proto.distanceToSphere = function distanceToSphere(sphere) { + return this.distanceToPoint(sphere.center) - sphere.radius; + }; - setEulerFromRotationMatrix: function ( m, order ) { + _proto.projectPoint = function projectPoint(point, target) { + if (target === undefined) { + console.warn('THREE.Plane: .projectPoint() target is now required'); + target = new Vector3(); + } - console.error( "REMOVED: Vector3\'s setEulerFromRotationMatrix has been removed in favor of Euler.setFromRotationMatrix(), please update your code."); + return target.copy(this.normal).multiplyScalar(-this.distanceToPoint(point)).add(point); + }; - }, + _proto.intersectLine = function intersectLine(line, target) { + if (target === undefined) { + console.warn('THREE.Plane: .intersectLine() target is now required'); + target = new Vector3(); + } - setEulerFromQuaternion: function ( q, order ) { + var direction = line.delta(_vector1); + var denominator = this.normal.dot(direction); - console.error( "REMOVED: Vector3\'s setEulerFromQuaternion: has been removed in favor of Euler.setFromQuaternion(), please update your code."); + if (denominator === 0) { + // line is coplanar, return origin + if (this.distanceToPoint(line.start) === 0) { + return target.copy(line.start); + } // Unsure if this is the correct method to handle this case. - }, - getPositionFromMatrix: function ( m ) { + return undefined; + } - console.warn( "DEPRECATED: Vector3\'s .getPositionFromMatrix() has been renamed to .setFromMatrixPosition(). Please update your code." ); + var t = -(line.start.dot(this.normal) + this.constant) / denominator; - return this.setFromMatrixPosition( m ); + if (t < 0 || t > 1) { + return undefined; + } - }, + return target.copy(direction).multiplyScalar(t).add(line.start); + }; - getScaleFromMatrix: function ( m ) { + _proto.intersectsLine = function intersectsLine(line) { + // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. + var startSign = this.distanceToPoint(line.start); + var endSign = this.distanceToPoint(line.end); + return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0; + }; - console.warn( "DEPRECATED: Vector3\'s .getScaleFromMatrix() has been renamed to .setFromMatrixScale(). Please update your code." ); + _proto.intersectsBox = function intersectsBox(box) { + return box.intersectsPlane(this); + }; - return this.setFromMatrixScale( m ); - }, + _proto.intersectsSphere = function intersectsSphere(sphere) { + return sphere.intersectsPlane(this); + }; - getColumnFromMatrix: function ( index, matrix ) { + _proto.coplanarPoint = function coplanarPoint(target) { + if (target === undefined) { + console.warn('THREE.Plane: .coplanarPoint() target is now required'); + target = new Vector3(); + } - console.warn( "DEPRECATED: Vector3\'s .getColumnFromMatrix() has been renamed to .setFromMatrixColumn(). Please update your code." ); - - return this.setFromMatrixColumn( index, matrix ); + return target.copy(this.normal).multiplyScalar(-this.constant); + }; - }, + _proto.applyMatrix4 = function applyMatrix4(matrix, optionalNormalMatrix) { + var normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix); - setFromMatrixPosition: function ( m ) { + var referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix); + var normal = this.normal.applyMatrix3(normalMatrix).normalize(); + this.constant = -referencePoint.dot(normal); + return this; + }; - this.x = m.elements[ 12 ]; - this.y = m.elements[ 13 ]; - this.z = m.elements[ 14 ]; + _proto.translate = function translate(offset) { + this.constant -= offset.dot(this.normal); + return this; + }; - return this; + _proto.equals = function equals(plane) { + return plane.normal.equals(this.normal) && plane.constant === this.constant; + }; - }, + return Plane; + }(); - setFromMatrixScale: function ( m ) { + var _v0$1 = /*@__PURE__*/new Vector3(); - var sx = this.set( m.elements[ 0 ], m.elements[ 1 ], m.elements[ 2 ] ).length(); - var sy = this.set( m.elements[ 4 ], m.elements[ 5 ], m.elements[ 6 ] ).length(); - var sz = this.set( m.elements[ 8 ], m.elements[ 9 ], m.elements[ 10 ] ).length(); + var _v1$3 = /*@__PURE__*/new Vector3(); - this.x = sx; - this.y = sy; - this.z = sz; + var _v2$1 = /*@__PURE__*/new Vector3(); - return this; - }, + var _v3 = /*@__PURE__*/new Vector3(); - setFromMatrixColumn: function ( index, matrix ) { + var _vab = /*@__PURE__*/new Vector3(); - var offset = index * 4; + var _vac = /*@__PURE__*/new Vector3(); - var me = matrix.elements; + var _vbc = /*@__PURE__*/new Vector3(); - this.x = me[ offset ]; - this.y = me[ offset + 1 ]; - this.z = me[ offset + 2 ]; + var _vap = /*@__PURE__*/new Vector3(); - return this; + var _vbp = /*@__PURE__*/new Vector3(); - }, + var _vcp = /*@__PURE__*/new Vector3(); - equals: function ( v ) { + var Triangle = /*#__PURE__*/function () { + function Triangle(a, b, c) { + this.a = a !== undefined ? a : new Vector3(); + this.b = b !== undefined ? b : new Vector3(); + this.c = c !== undefined ? c : new Vector3(); + } - return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); + Triangle.getNormal = function getNormal(a, b, c, target) { + if (target === undefined) { + console.warn('THREE.Triangle: .getNormal() target is now required'); + target = new Vector3(); + } - }, + target.subVectors(c, b); - fromArray: function ( array ) { + _v0$1.subVectors(a, b); - this.x = array[ 0 ]; - this.y = array[ 1 ]; - this.z = array[ 2 ]; + target.cross(_v0$1); + var targetLengthSq = target.lengthSq(); - return this; + if (targetLengthSq > 0) { + return target.multiplyScalar(1 / Math.sqrt(targetLengthSq)); + } - }, + return target.set(0, 0, 0); + } // static/instance method to calculate barycentric coordinates + // based on: http://www.blackpawn.com/texts/pointinpoly/default.html + ; - toArray: function () { + Triangle.getBarycoord = function getBarycoord(point, a, b, c, target) { + _v0$1.subVectors(c, a); - return [ this.x, this.y, this.z ]; + _v1$3.subVectors(b, a); - }, + _v2$1.subVectors(point, a); - clone: function () { + var dot00 = _v0$1.dot(_v0$1); - return new THREE.Vector3( this.x, this.y, this.z ); + var dot01 = _v0$1.dot(_v1$3); - } + var dot02 = _v0$1.dot(_v2$1); -}; -/** - * @author supereggbert / http://www.paulbrunt.co.uk/ - * @author philogb / http://blog.thejit.org/ - * @author mikael emtinger / http://gomo.se/ - * @author egraether / http://egraether.com/ - * @author WestLangley / http://github.com/WestLangley - */ + var dot11 = _v1$3.dot(_v1$3); -THREE.Vector4 = function ( x, y, z, w ) { + var dot12 = _v1$3.dot(_v2$1); - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - this.w = ( w !== undefined ) ? w : 1; + var denom = dot00 * dot11 - dot01 * dot01; -}; + if (target === undefined) { + console.warn('THREE.Triangle: .getBarycoord() target is now required'); + target = new Vector3(); + } // collinear or singular triangle -THREE.Vector4.prototype = { - constructor: THREE.Vector4, + if (denom === 0) { + // arbitrary location outside of triangle? + // not sure if this is the best idea, maybe should be returning undefined + return target.set(-2, -1, -1); + } - set: function ( x, y, z, w ) { + var invDenom = 1 / denom; + var u = (dot11 * dot02 - dot01 * dot12) * invDenom; + var v = (dot00 * dot12 - dot01 * dot02) * invDenom; // barycentric coordinates must always sum to 1 - this.x = x; - this.y = y; - this.z = z; - this.w = w; + return target.set(1 - u - v, v, u); + }; - return this; + Triangle.containsPoint = function containsPoint(point, a, b, c) { + this.getBarycoord(point, a, b, c, _v3); + return _v3.x >= 0 && _v3.y >= 0 && _v3.x + _v3.y <= 1; + }; - }, + Triangle.getUV = function getUV(point, p1, p2, p3, uv1, uv2, uv3, target) { + this.getBarycoord(point, p1, p2, p3, _v3); + target.set(0, 0); + target.addScaledVector(uv1, _v3.x); + target.addScaledVector(uv2, _v3.y); + target.addScaledVector(uv3, _v3.z); + return target; + }; - setX: function ( x ) { + Triangle.isFrontFacing = function isFrontFacing(a, b, c, direction) { + _v0$1.subVectors(c, b); - this.x = x; + _v1$3.subVectors(a, b); // strictly front facing - return this; - }, + return _v0$1.cross(_v1$3).dot(direction) < 0 ? true : false; + }; - setY: function ( y ) { + var _proto = Triangle.prototype; - this.y = y; + _proto.set = function set(a, b, c) { + this.a.copy(a); + this.b.copy(b); + this.c.copy(c); + return this; + }; - return this; + _proto.setFromPointsAndIndices = function setFromPointsAndIndices(points, i0, i1, i2) { + this.a.copy(points[i0]); + this.b.copy(points[i1]); + this.c.copy(points[i2]); + return this; + }; - }, + _proto.clone = function clone() { + return new this.constructor().copy(this); + }; - setZ: function ( z ) { + _proto.copy = function copy(triangle) { + this.a.copy(triangle.a); + this.b.copy(triangle.b); + this.c.copy(triangle.c); + return this; + }; - this.z = z; + _proto.getArea = function getArea() { + _v0$1.subVectors(this.c, this.b); - return this; + _v1$3.subVectors(this.a, this.b); - }, + return _v0$1.cross(_v1$3).length() * 0.5; + }; - setW: function ( w ) { + _proto.getMidpoint = function getMidpoint(target) { + if (target === undefined) { + console.warn('THREE.Triangle: .getMidpoint() target is now required'); + target = new Vector3(); + } - this.w = w; + return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3); + }; - return this; + _proto.getNormal = function getNormal(target) { + return Triangle.getNormal(this.a, this.b, this.c, target); + }; - }, + _proto.getPlane = function getPlane(target) { + if (target === undefined) { + console.warn('THREE.Triangle: .getPlane() target is now required'); + target = new Plane(); + } - setComponent: function ( index, value ) { + return target.setFromCoplanarPoints(this.a, this.b, this.c); + }; - switch ( index ) { + _proto.getBarycoord = function getBarycoord(point, target) { + return Triangle.getBarycoord(point, this.a, this.b, this.c, target); + }; - case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - case 3: this.w = value; break; - default: throw new Error( "index is out of range: " + index ); + _proto.getUV = function getUV(point, uv1, uv2, uv3, target) { + return Triangle.getUV(point, this.a, this.b, this.c, uv1, uv2, uv3, target); + }; - } + _proto.containsPoint = function containsPoint(point) { + return Triangle.containsPoint(point, this.a, this.b, this.c); + }; - }, + _proto.isFrontFacing = function isFrontFacing(direction) { + return Triangle.isFrontFacing(this.a, this.b, this.c, direction); + }; - getComponent: function ( index ) { + _proto.intersectsBox = function intersectsBox(box) { + return box.intersectsTriangle(this); + }; - switch ( index ) { + _proto.closestPointToPoint = function closestPointToPoint(p, target) { + if (target === undefined) { + console.warn('THREE.Triangle: .closestPointToPoint() target is now required'); + target = new Vector3(); + } - case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - case 3: return this.w; - default: throw new Error( "index is out of range: " + index ); + var a = this.a, + b = this.b, + c = this.c; + var v, w; // algorithm thanks to Real-Time Collision Detection by Christer Ericson, + // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., + // under the accompanying license; see chapter 5.1.5 for detailed explanation. + // basically, we're distinguishing which of the voronoi regions of the triangle + // the point lies in with the minimum amount of redundant computation. - } + _vab.subVectors(b, a); - }, + _vac.subVectors(c, a); - copy: function ( v ) { + _vap.subVectors(p, a); - this.x = v.x; - this.y = v.y; - this.z = v.z; - this.w = ( v.w !== undefined ) ? v.w : 1; + var d1 = _vab.dot(_vap); - return this; + var d2 = _vac.dot(_vap); - }, + if (d1 <= 0 && d2 <= 0) { + // vertex region of A; barycentric coords (1, 0, 0) + return target.copy(a); + } - add: function ( v, w ) { + _vbp.subVectors(p, b); - if ( w !== undefined ) { + var d3 = _vab.dot(_vbp); - console.warn( 'DEPRECATED: Vector4\'s .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); + var d4 = _vac.dot(_vbp); - } + if (d3 >= 0 && d4 <= d3) { + // vertex region of B; barycentric coords (0, 1, 0) + return target.copy(b); + } - this.x += v.x; - this.y += v.y; - this.z += v.z; - this.w += v.w; + var vc = d1 * d4 - d3 * d2; - return this; + if (vc <= 0 && d1 >= 0 && d3 <= 0) { + v = d1 / (d1 - d3); // edge region of AB; barycentric coords (1-v, v, 0) - }, + return target.copy(a).addScaledVector(_vab, v); + } - addScalar: function ( s ) { + _vcp.subVectors(p, c); - this.x += s; - this.y += s; - this.z += s; - this.w += s; + var d5 = _vab.dot(_vcp); - return this; + var d6 = _vac.dot(_vcp); - }, + if (d6 >= 0 && d5 <= d6) { + // vertex region of C; barycentric coords (0, 0, 1) + return target.copy(c); + } - addVectors: function ( a, b ) { + var vb = d5 * d2 - d1 * d6; - this.x = a.x + b.x; - this.y = a.y + b.y; - this.z = a.z + b.z; - this.w = a.w + b.w; + if (vb <= 0 && d2 >= 0 && d6 <= 0) { + w = d2 / (d2 - d6); // edge region of AC; barycentric coords (1-w, 0, w) - return this; + return target.copy(a).addScaledVector(_vac, w); + } - }, + var va = d3 * d6 - d5 * d4; - sub: function ( v, w ) { + if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) { + _vbc.subVectors(c, b); - if ( w !== undefined ) { + w = (d4 - d3) / (d4 - d3 + (d5 - d6)); // edge region of BC; barycentric coords (0, 1-w, w) - console.warn( 'DEPRECATED: Vector4\'s .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); + return target.copy(b).addScaledVector(_vbc, w); // edge region of BC + } // face region - } - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - this.w -= v.w; + var denom = 1 / (va + vb + vc); // u = va * denom - return this; + v = vb * denom; + w = vc * denom; + return target.copy(a).addScaledVector(_vab, v).addScaledVector(_vac, w); + }; - }, + _proto.equals = function equals(triangle) { + return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c); + }; - subVectors: function ( a, b ) { + return Triangle; + }(); - this.x = a.x - b.x; - this.y = a.y - b.y; - this.z = a.z - b.z; - this.w = a.w - b.w; + var _colorKeywords = { + 'aliceblue': 0xF0F8FF, + 'antiquewhite': 0xFAEBD7, + 'aqua': 0x00FFFF, + 'aquamarine': 0x7FFFD4, + 'azure': 0xF0FFFF, + 'beige': 0xF5F5DC, + 'bisque': 0xFFE4C4, + 'black': 0x000000, + 'blanchedalmond': 0xFFEBCD, + 'blue': 0x0000FF, + 'blueviolet': 0x8A2BE2, + 'brown': 0xA52A2A, + 'burlywood': 0xDEB887, + 'cadetblue': 0x5F9EA0, + 'chartreuse': 0x7FFF00, + 'chocolate': 0xD2691E, + 'coral': 0xFF7F50, + 'cornflowerblue': 0x6495ED, + 'cornsilk': 0xFFF8DC, + 'crimson': 0xDC143C, + 'cyan': 0x00FFFF, + 'darkblue': 0x00008B, + 'darkcyan': 0x008B8B, + 'darkgoldenrod': 0xB8860B, + 'darkgray': 0xA9A9A9, + 'darkgreen': 0x006400, + 'darkgrey': 0xA9A9A9, + 'darkkhaki': 0xBDB76B, + 'darkmagenta': 0x8B008B, + 'darkolivegreen': 0x556B2F, + 'darkorange': 0xFF8C00, + 'darkorchid': 0x9932CC, + 'darkred': 0x8B0000, + 'darksalmon': 0xE9967A, + 'darkseagreen': 0x8FBC8F, + 'darkslateblue': 0x483D8B, + 'darkslategray': 0x2F4F4F, + 'darkslategrey': 0x2F4F4F, + 'darkturquoise': 0x00CED1, + 'darkviolet': 0x9400D3, + 'deeppink': 0xFF1493, + 'deepskyblue': 0x00BFFF, + 'dimgray': 0x696969, + 'dimgrey': 0x696969, + 'dodgerblue': 0x1E90FF, + 'firebrick': 0xB22222, + 'floralwhite': 0xFFFAF0, + 'forestgreen': 0x228B22, + 'fuchsia': 0xFF00FF, + 'gainsboro': 0xDCDCDC, + 'ghostwhite': 0xF8F8FF, + 'gold': 0xFFD700, + 'goldenrod': 0xDAA520, + 'gray': 0x808080, + 'green': 0x008000, + 'greenyellow': 0xADFF2F, + 'grey': 0x808080, + 'honeydew': 0xF0FFF0, + 'hotpink': 0xFF69B4, + 'indianred': 0xCD5C5C, + 'indigo': 0x4B0082, + 'ivory': 0xFFFFF0, + 'khaki': 0xF0E68C, + 'lavender': 0xE6E6FA, + 'lavenderblush': 0xFFF0F5, + 'lawngreen': 0x7CFC00, + 'lemonchiffon': 0xFFFACD, + 'lightblue': 0xADD8E6, + 'lightcoral': 0xF08080, + 'lightcyan': 0xE0FFFF, + 'lightgoldenrodyellow': 0xFAFAD2, + 'lightgray': 0xD3D3D3, + 'lightgreen': 0x90EE90, + 'lightgrey': 0xD3D3D3, + 'lightpink': 0xFFB6C1, + 'lightsalmon': 0xFFA07A, + 'lightseagreen': 0x20B2AA, + 'lightskyblue': 0x87CEFA, + 'lightslategray': 0x778899, + 'lightslategrey': 0x778899, + 'lightsteelblue': 0xB0C4DE, + 'lightyellow': 0xFFFFE0, + 'lime': 0x00FF00, + 'limegreen': 0x32CD32, + 'linen': 0xFAF0E6, + 'magenta': 0xFF00FF, + 'maroon': 0x800000, + 'mediumaquamarine': 0x66CDAA, + 'mediumblue': 0x0000CD, + 'mediumorchid': 0xBA55D3, + 'mediumpurple': 0x9370DB, + 'mediumseagreen': 0x3CB371, + 'mediumslateblue': 0x7B68EE, + 'mediumspringgreen': 0x00FA9A, + 'mediumturquoise': 0x48D1CC, + 'mediumvioletred': 0xC71585, + 'midnightblue': 0x191970, + 'mintcream': 0xF5FFFA, + 'mistyrose': 0xFFE4E1, + 'moccasin': 0xFFE4B5, + 'navajowhite': 0xFFDEAD, + 'navy': 0x000080, + 'oldlace': 0xFDF5E6, + 'olive': 0x808000, + 'olivedrab': 0x6B8E23, + 'orange': 0xFFA500, + 'orangered': 0xFF4500, + 'orchid': 0xDA70D6, + 'palegoldenrod': 0xEEE8AA, + 'palegreen': 0x98FB98, + 'paleturquoise': 0xAFEEEE, + 'palevioletred': 0xDB7093, + 'papayawhip': 0xFFEFD5, + 'peachpuff': 0xFFDAB9, + 'peru': 0xCD853F, + 'pink': 0xFFC0CB, + 'plum': 0xDDA0DD, + 'powderblue': 0xB0E0E6, + 'purple': 0x800080, + 'rebeccapurple': 0x663399, + 'red': 0xFF0000, + 'rosybrown': 0xBC8F8F, + 'royalblue': 0x4169E1, + 'saddlebrown': 0x8B4513, + 'salmon': 0xFA8072, + 'sandybrown': 0xF4A460, + 'seagreen': 0x2E8B57, + 'seashell': 0xFFF5EE, + 'sienna': 0xA0522D, + 'silver': 0xC0C0C0, + 'skyblue': 0x87CEEB, + 'slateblue': 0x6A5ACD, + 'slategray': 0x708090, + 'slategrey': 0x708090, + 'snow': 0xFFFAFA, + 'springgreen': 0x00FF7F, + 'steelblue': 0x4682B4, + 'tan': 0xD2B48C, + 'teal': 0x008080, + 'thistle': 0xD8BFD8, + 'tomato': 0xFF6347, + 'turquoise': 0x40E0D0, + 'violet': 0xEE82EE, + 'wheat': 0xF5DEB3, + 'white': 0xFFFFFF, + 'whitesmoke': 0xF5F5F5, + 'yellow': 0xFFFF00, + 'yellowgreen': 0x9ACD32 + }; + var _hslA = { + h: 0, + s: 0, + l: 0 + }; + var _hslB = { + h: 0, + s: 0, + l: 0 + }; - return this; + function hue2rgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t); + return p; + } - }, + function SRGBToLinear(c) { + return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4); + } - multiplyScalar: function ( scalar ) { + function LinearToSRGB(c) { + return c < 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055; + } - this.x *= scalar; - this.y *= scalar; - this.z *= scalar; - this.w *= scalar; + var Color = /*#__PURE__*/function () { + function Color(r, g, b) { + Object.defineProperty(this, 'isColor', { + value: true + }); - return this; + if (g === undefined && b === undefined) { + // r is THREE.Color, hex or string + return this.set(r); + } - }, + return this.setRGB(r, g, b); + } - applyMatrix4: function ( m ) { + var _proto = Color.prototype; - var x = this.x; - var y = this.y; - var z = this.z; - var w = this.w; + _proto.set = function set(value) { + if (value && value.isColor) { + this.copy(value); + } else if (typeof value === 'number') { + this.setHex(value); + } else if (typeof value === 'string') { + this.setStyle(value); + } - var e = m.elements; + return this; + }; - 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; - this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w; + _proto.setScalar = function setScalar(scalar) { + this.r = scalar; + this.g = scalar; + this.b = scalar; + return this; + }; - return this; + _proto.setHex = function setHex(hex) { + hex = Math.floor(hex); + this.r = (hex >> 16 & 255) / 255; + this.g = (hex >> 8 & 255) / 255; + this.b = (hex & 255) / 255; + return this; + }; - }, + _proto.setRGB = function setRGB(r, g, b) { + this.r = r; + this.g = g; + this.b = b; + return this; + }; - divideScalar: function ( scalar ) { + _proto.setHSL = function setHSL(h, s, l) { + // h,s,l ranges are in 0.0 - 1.0 + h = MathUtils.euclideanModulo(h, 1); + s = MathUtils.clamp(s, 0, 1); + l = MathUtils.clamp(l, 0, 1); - if ( scalar !== 0 ) { + if (s === 0) { + this.r = this.g = this.b = l; + } else { + var p = l <= 0.5 ? l * (1 + s) : l + s - l * s; + var q = 2 * l - p; + this.r = hue2rgb(q, p, h + 1 / 3); + this.g = hue2rgb(q, p, h); + this.b = hue2rgb(q, p, h - 1 / 3); + } - var invScalar = 1 / scalar; + return this; + }; - this.x *= invScalar; - this.y *= invScalar; - this.z *= invScalar; - this.w *= invScalar; + _proto.setStyle = function setStyle(style) { + function handleAlpha(string) { + if (string === undefined) return; - } else { + if (parseFloat(string) < 1) { + console.warn('THREE.Color: Alpha component of ' + style + ' will be ignored.'); + } + } - this.x = 0; - this.y = 0; - this.z = 0; - this.w = 1; + var m; + + if (m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(style)) { + // rgb / hsl + var color; + var name = m[1]; + var components = m[2]; + + switch (name) { + case 'rgb': + case 'rgba': + if (color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(components)) { + // rgb(255,0,0) rgba(255,0,0,0.5) + this.r = Math.min(255, parseInt(color[1], 10)) / 255; + this.g = Math.min(255, parseInt(color[2], 10)) / 255; + this.b = Math.min(255, parseInt(color[3], 10)) / 255; + handleAlpha(color[5]); + return this; + } - } + if (color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(components)) { + // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) + this.r = Math.min(100, parseInt(color[1], 10)) / 100; + this.g = Math.min(100, parseInt(color[2], 10)) / 100; + this.b = Math.min(100, parseInt(color[3], 10)) / 100; + handleAlpha(color[5]); + return this; + } - return this; + break; - }, + case 'hsl': + case 'hsla': + if (color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(components)) { + // hsl(120,50%,50%) hsla(120,50%,50%,0.5) + var h = parseFloat(color[1]) / 360; + var s = parseInt(color[2], 10) / 100; + var l = parseInt(color[3], 10) / 100; + handleAlpha(color[5]); + return this.setHSL(h, s, l); + } - setAxisAngleFromQuaternion: function ( q ) { + break; + } + } else if (m = /^\#([A-Fa-f0-9]+)$/.exec(style)) { + // hex color + var hex = m[1]; + var size = hex.length; + + if (size === 3) { + // #ff0 + this.r = parseInt(hex.charAt(0) + hex.charAt(0), 16) / 255; + this.g = parseInt(hex.charAt(1) + hex.charAt(1), 16) / 255; + this.b = parseInt(hex.charAt(2) + hex.charAt(2), 16) / 255; + return this; + } else if (size === 6) { + // #ff0000 + this.r = parseInt(hex.charAt(0) + hex.charAt(1), 16) / 255; + this.g = parseInt(hex.charAt(2) + hex.charAt(3), 16) / 255; + this.b = parseInt(hex.charAt(4) + hex.charAt(5), 16) / 255; + return this; + } + } - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm + if (style && style.length > 0) { + return this.setColorName(style); + } - // q is assumed to be normalized + return this; + }; - this.w = 2 * Math.acos( q.w ); + _proto.setColorName = function setColorName(style) { + // color keywords + var hex = _colorKeywords[style]; - var s = Math.sqrt( 1 - q.w * q.w ); + if (hex !== undefined) { + // red + this.setHex(hex); + } else { + // unknown color + console.warn('THREE.Color: Unknown color ' + style); + } - if ( s < 0.0001 ) { + return this; + }; - this.x = 1; - this.y = 0; - this.z = 0; + _proto.clone = function clone() { + return new this.constructor(this.r, this.g, this.b); + }; - } else { + _proto.copy = function copy(color) { + this.r = color.r; + this.g = color.g; + this.b = color.b; + return this; + }; - this.x = q.x / s; - this.y = q.y / s; - this.z = q.z / s; + _proto.copyGammaToLinear = function copyGammaToLinear(color, gammaFactor) { + if (gammaFactor === undefined) gammaFactor = 2.0; + this.r = Math.pow(color.r, gammaFactor); + this.g = Math.pow(color.g, gammaFactor); + this.b = Math.pow(color.b, gammaFactor); + return this; + }; - } + _proto.copyLinearToGamma = function copyLinearToGamma(color, gammaFactor) { + if (gammaFactor === undefined) gammaFactor = 2.0; + var safeInverse = gammaFactor > 0 ? 1.0 / gammaFactor : 1.0; + this.r = Math.pow(color.r, safeInverse); + this.g = Math.pow(color.g, safeInverse); + this.b = Math.pow(color.b, safeInverse); + return this; + }; - return this; + _proto.convertGammaToLinear = function convertGammaToLinear(gammaFactor) { + this.copyGammaToLinear(this, gammaFactor); + return this; + }; - }, + _proto.convertLinearToGamma = function convertLinearToGamma(gammaFactor) { + this.copyLinearToGamma(this, gammaFactor); + return this; + }; - setAxisAngleFromRotationMatrix: function ( m ) { + _proto.copySRGBToLinear = function copySRGBToLinear(color) { + this.r = SRGBToLinear(color.r); + this.g = SRGBToLinear(color.g); + this.b = SRGBToLinear(color.b); + return this; + }; - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm + _proto.copyLinearToSRGB = function copyLinearToSRGB(color) { + this.r = LinearToSRGB(color.r); + this.g = LinearToSRGB(color.g); + this.b = LinearToSRGB(color.b); + return this; + }; - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + _proto.convertSRGBToLinear = function convertSRGBToLinear() { + this.copySRGBToLinear(this); + return this; + }; - var angle, x, y, z, // variables for result - epsilon = 0.01, // margin to allow for rounding errors - epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees + _proto.convertLinearToSRGB = function convertLinearToSRGB() { + this.copyLinearToSRGB(this); + return this; + }; - te = m.elements, + _proto.getHex = function getHex() { + return this.r * 255 << 16 ^ this.g * 255 << 8 ^ this.b * 255 << 0; + }; - 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]; + _proto.getHexString = function getHexString() { + return ('000000' + this.getHex().toString(16)).slice(-6); + }; - if ( ( Math.abs( m12 - m21 ) < epsilon ) - && ( Math.abs( m13 - m31 ) < epsilon ) - && ( Math.abs( m23 - m32 ) < epsilon ) ) { + _proto.getHSL = function getHSL(target) { + // h,s,l ranges are in 0.0 - 1.0 + if (target === undefined) { + console.warn('THREE.Color: .getHSL() target is now required'); + target = { + h: 0, + s: 0, + l: 0 + }; + } - // singularity found - // first check for identity matrix which must have +1 for all terms - // in leading diagonal and zero in other terms + var r = this.r, + g = this.g, + b = this.b; + var max = Math.max(r, g, b); + var min = Math.min(r, g, b); + var hue, saturation; + var lightness = (min + max) / 2.0; - if ( ( Math.abs( m12 + m21 ) < epsilon2 ) - && ( Math.abs( m13 + m31 ) < epsilon2 ) - && ( Math.abs( m23 + m32 ) < epsilon2 ) - && ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { + if (min === max) { + hue = 0; + saturation = 0; + } else { + var delta = max - min; + saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min); - // this singularity is identity matrix so angle = 0 + switch (max) { + case r: + hue = (g - b) / delta + (g < b ? 6 : 0); + break; - this.set( 1, 0, 0, 0 ); + case g: + hue = (b - r) / delta + 2; + break; - return this; // zero angle, arbitrary axis + case b: + hue = (r - g) / delta + 4; + break; + } + hue /= 6; } - // otherwise this singularity is angle = 180 - - angle = Math.PI; + target.h = hue; + target.s = saturation; + target.l = lightness; + return target; + }; - var xx = ( m11 + 1 ) / 2; - var yy = ( m22 + 1 ) / 2; - var zz = ( m33 + 1 ) / 2; - var xy = ( m12 + m21 ) / 4; - var xz = ( m13 + m31 ) / 4; - var yz = ( m23 + m32 ) / 4; + _proto.getStyle = function getStyle() { + return 'rgb(' + (this.r * 255 | 0) + ',' + (this.g * 255 | 0) + ',' + (this.b * 255 | 0) + ')'; + }; - if ( ( xx > yy ) && ( xx > zz ) ) { // m11 is the largest diagonal term + _proto.offsetHSL = function offsetHSL(h, s, l) { + this.getHSL(_hslA); + _hslA.h += h; + _hslA.s += s; + _hslA.l += l; + this.setHSL(_hslA.h, _hslA.s, _hslA.l); + return this; + }; - if ( xx < epsilon ) { + _proto.add = function add(color) { + this.r += color.r; + this.g += color.g; + this.b += color.b; + return this; + }; - x = 0; - y = 0.707106781; - z = 0.707106781; + _proto.addColors = function addColors(color1, color2) { + this.r = color1.r + color2.r; + this.g = color1.g + color2.g; + this.b = color1.b + color2.b; + return this; + }; - } else { + _proto.addScalar = function addScalar(s) { + this.r += s; + this.g += s; + this.b += s; + return this; + }; - x = Math.sqrt( xx ); - y = xy / x; - z = xz / x; + _proto.sub = function sub(color) { + this.r = Math.max(0, this.r - color.r); + this.g = Math.max(0, this.g - color.g); + this.b = Math.max(0, this.b - color.b); + return this; + }; - } + _proto.multiply = function multiply(color) { + this.r *= color.r; + this.g *= color.g; + this.b *= color.b; + return this; + }; - } else if ( yy > zz ) { // m22 is the largest diagonal term + _proto.multiplyScalar = function multiplyScalar(s) { + this.r *= s; + this.g *= s; + this.b *= s; + return this; + }; - if ( yy < epsilon ) { + _proto.lerp = function lerp(color, alpha) { + this.r += (color.r - this.r) * alpha; + this.g += (color.g - this.g) * alpha; + this.b += (color.b - this.b) * alpha; + return this; + }; - x = 0.707106781; - y = 0; - z = 0.707106781; + _proto.lerpHSL = function lerpHSL(color, alpha) { + this.getHSL(_hslA); + color.getHSL(_hslB); + var h = MathUtils.lerp(_hslA.h, _hslB.h, alpha); + var s = MathUtils.lerp(_hslA.s, _hslB.s, alpha); + var l = MathUtils.lerp(_hslA.l, _hslB.l, alpha); + this.setHSL(h, s, l); + return this; + }; - } else { + _proto.equals = function equals(c) { + return c.r === this.r && c.g === this.g && c.b === this.b; + }; - y = Math.sqrt( yy ); - x = xy / y; - z = yz / y; + _proto.fromArray = function fromArray(array, offset) { + if (offset === void 0) { + offset = 0; + } - } + this.r = array[offset]; + this.g = array[offset + 1]; + this.b = array[offset + 2]; + return this; + }; - } else { // m33 is the largest diagonal term so base result on this + _proto.toArray = function toArray(array, offset) { + if (array === void 0) { + array = []; + } - if ( zz < epsilon ) { + if (offset === void 0) { + offset = 0; + } - x = 0.707106781; - y = 0.707106781; - z = 0; + array[offset] = this.r; + array[offset + 1] = this.g; + array[offset + 2] = this.b; + return array; + }; - } else { + _proto.fromBufferAttribute = function fromBufferAttribute(attribute, index) { + this.r = attribute.getX(index); + this.g = attribute.getY(index); + this.b = attribute.getZ(index); - z = Math.sqrt( zz ); - x = xz / z; - y = yz / z; + if (attribute.normalized === true) { + // assuming Uint8Array + this.r /= 255; + this.g /= 255; + this.b /= 255; + } - } + return this; + }; - } + _proto.toJSON = function toJSON() { + return this.getHex(); + }; - this.set( x, y, z, angle ); + return Color; + }(); - return this; // return 180 deg rotation + Color.NAMES = _colorKeywords; + Color.prototype.r = 1; + Color.prototype.g = 1; + Color.prototype.b = 1; + var Face3 = /*#__PURE__*/function () { + function Face3(a, b, c, normal, color, materialIndex) { + this.a = a; + this.b = b; + this.c = c; + this.normal = normal && normal.isVector3 ? normal : new Vector3(); + this.vertexNormals = Array.isArray(normal) ? normal : []; + this.color = color && color.isColor ? color : new Color(); + this.vertexColors = Array.isArray(color) ? color : []; + this.materialIndex = materialIndex !== undefined ? materialIndex : 0; } - // as we have reached here there are no singularities so we can handle normally + var _proto = Face3.prototype; - var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) - + ( m13 - m31 ) * ( m13 - m31 ) - + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize + _proto.clone = function clone() { + return new this.constructor().copy(this); + }; - if ( Math.abs( s ) < 0.001 ) s = 1; + _proto.copy = function copy(source) { + this.a = source.a; + this.b = source.b; + this.c = source.c; + this.normal.copy(source.normal); + this.color.copy(source.color); + this.materialIndex = source.materialIndex; - // prevent divide by zero, should not happen if matrix is orthogonal and should be - // caught by singularity test above, but I've left it in just in case + for (var i = 0, il = source.vertexNormals.length; i < il; i++) { + this.vertexNormals[i] = source.vertexNormals[i].clone(); + } - this.x = ( m32 - m23 ) / s; - this.y = ( m13 - m31 ) / s; - this.z = ( m21 - m12 ) / s; - this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); + for (var _i = 0, _il = source.vertexColors.length; _i < _il; _i++) { + this.vertexColors[_i] = source.vertexColors[_i].clone(); + } - return this; + return this; + }; - }, + return Face3; + }(); - min: function ( v ) { + var materialId = 0; + + function Material() { + Object.defineProperty(this, 'id', { + value: materialId++ + }); + this.uuid = MathUtils.generateUUID(); + this.name = ''; + this.type = 'Material'; + this.fog = true; + this.blending = NormalBlending; + this.side = FrontSide; + this.flatShading = false; + this.vertexColors = false; + this.opacity = 1; + this.transparent = false; + this.blendSrc = SrcAlphaFactor; + this.blendDst = OneMinusSrcAlphaFactor; + this.blendEquation = AddEquation; + this.blendSrcAlpha = null; + this.blendDstAlpha = null; + this.blendEquationAlpha = null; + this.depthFunc = LessEqualDepth; + this.depthTest = true; + this.depthWrite = true; + this.stencilWriteMask = 0xff; + this.stencilFunc = AlwaysStencilFunc; + this.stencilRef = 0; + this.stencilFuncMask = 0xff; + this.stencilFail = KeepStencilOp; + this.stencilZFail = KeepStencilOp; + this.stencilZPass = KeepStencilOp; + this.stencilWrite = false; + this.clippingPlanes = null; + this.clipIntersection = false; + this.clipShadows = false; + this.shadowSide = null; + this.colorWrite = true; + this.precision = null; // override the renderer's default precision for this material + + this.polygonOffset = false; + this.polygonOffsetFactor = 0; + this.polygonOffsetUnits = 0; + this.dithering = false; + this.alphaTest = 0; + this.premultipliedAlpha = false; + this.visible = true; + this.toneMapped = true; + this.userData = {}; + this.version = 0; + } + + Material.prototype = Object.assign(Object.create(EventDispatcher.prototype), { + constructor: Material, + isMaterial: true, + onBeforeCompile: function onBeforeCompile() + /* shaderobject, renderer */ + {}, + customProgramCacheKey: function customProgramCacheKey() { + return this.onBeforeCompile.toString(); + }, + setValues: function setValues(values) { + if (values === undefined) return; - if ( this.x > v.x ) { + for (var key in values) { + var newValue = values[key]; - this.x = v.x; + if (newValue === undefined) { + console.warn("THREE.Material: '" + key + "' parameter is undefined."); + continue; + } // for backward compatability if shading is set in the constructor - } - if ( this.y > v.y ) { + if (key === 'shading') { + console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.'); + this.flatShading = newValue === FlatShading ? true : false; + continue; + } - this.y = v.y; + var currentValue = this[key]; - } + if (currentValue === undefined) { + console.warn("THREE." + this.type + ": '" + key + "' is not a property of this material."); + continue; + } - if ( this.z > v.z ) { + if (currentValue && currentValue.isColor) { + currentValue.set(newValue); + } else if (currentValue && currentValue.isVector3 && newValue && newValue.isVector3) { + currentValue.copy(newValue); + } else { + this[key] = newValue; + } + } + }, + toJSON: function toJSON(meta) { + var isRoot = meta === undefined || typeof meta === 'string'; - this.z = v.z; + if (isRoot) { + meta = { + textures: {}, + images: {} + }; + } - } + var data = { + metadata: { + version: 4.5, + type: 'Material', + generator: 'Material.toJSON' + } + }; // standard Material serialization + + data.uuid = this.uuid; + data.type = this.type; + if (this.name !== '') data.name = this.name; + if (this.color && this.color.isColor) data.color = this.color.getHex(); + if (this.roughness !== undefined) data.roughness = this.roughness; + if (this.metalness !== undefined) data.metalness = this.metalness; + if (this.sheen && this.sheen.isColor) data.sheen = this.sheen.getHex(); + if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex(); + if (this.emissiveIntensity && this.emissiveIntensity !== 1) data.emissiveIntensity = this.emissiveIntensity; + if (this.specular && this.specular.isColor) data.specular = this.specular.getHex(); + if (this.shininess !== undefined) data.shininess = this.shininess; + if (this.clearcoat !== undefined) data.clearcoat = this.clearcoat; + if (this.clearcoatRoughness !== undefined) data.clearcoatRoughness = this.clearcoatRoughness; + + if (this.clearcoatMap && this.clearcoatMap.isTexture) { + data.clearcoatMap = this.clearcoatMap.toJSON(meta).uuid; + } + + if (this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture) { + data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON(meta).uuid; + } + + if (this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture) { + data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON(meta).uuid; + data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); + } + + if (this.map && this.map.isTexture) data.map = this.map.toJSON(meta).uuid; + if (this.matcap && this.matcap.isTexture) data.matcap = this.matcap.toJSON(meta).uuid; + if (this.alphaMap && this.alphaMap.isTexture) data.alphaMap = this.alphaMap.toJSON(meta).uuid; + if (this.lightMap && this.lightMap.isTexture) data.lightMap = this.lightMap.toJSON(meta).uuid; + + if (this.aoMap && this.aoMap.isTexture) { + data.aoMap = this.aoMap.toJSON(meta).uuid; + data.aoMapIntensity = this.aoMapIntensity; + } + + if (this.bumpMap && this.bumpMap.isTexture) { + data.bumpMap = this.bumpMap.toJSON(meta).uuid; + data.bumpScale = this.bumpScale; + } + + if (this.normalMap && this.normalMap.isTexture) { + data.normalMap = this.normalMap.toJSON(meta).uuid; + data.normalMapType = this.normalMapType; + data.normalScale = this.normalScale.toArray(); + } + + if (this.displacementMap && this.displacementMap.isTexture) { + data.displacementMap = this.displacementMap.toJSON(meta).uuid; + data.displacementScale = this.displacementScale; + data.displacementBias = this.displacementBias; + } + + if (this.roughnessMap && this.roughnessMap.isTexture) data.roughnessMap = this.roughnessMap.toJSON(meta).uuid; + if (this.metalnessMap && this.metalnessMap.isTexture) data.metalnessMap = this.metalnessMap.toJSON(meta).uuid; + if (this.emissiveMap && this.emissiveMap.isTexture) data.emissiveMap = this.emissiveMap.toJSON(meta).uuid; + if (this.specularMap && this.specularMap.isTexture) data.specularMap = this.specularMap.toJSON(meta).uuid; + + if (this.envMap && this.envMap.isTexture) { + data.envMap = this.envMap.toJSON(meta).uuid; + data.reflectivity = this.reflectivity; // Scale behind envMap + + data.refractionRatio = this.refractionRatio; + if (this.combine !== undefined) data.combine = this.combine; + if (this.envMapIntensity !== undefined) data.envMapIntensity = this.envMapIntensity; + } + + if (this.gradientMap && this.gradientMap.isTexture) { + data.gradientMap = this.gradientMap.toJSON(meta).uuid; + } + + if (this.size !== undefined) data.size = this.size; + if (this.sizeAttenuation !== undefined) data.sizeAttenuation = this.sizeAttenuation; + if (this.blending !== NormalBlending) data.blending = this.blending; + if (this.flatShading === true) data.flatShading = this.flatShading; + if (this.side !== FrontSide) data.side = this.side; + if (this.vertexColors) data.vertexColors = true; + if (this.opacity < 1) data.opacity = this.opacity; + if (this.transparent === true) data.transparent = this.transparent; + data.depthFunc = this.depthFunc; + data.depthTest = this.depthTest; + data.depthWrite = this.depthWrite; + data.stencilWrite = this.stencilWrite; + data.stencilWriteMask = this.stencilWriteMask; + data.stencilFunc = this.stencilFunc; + data.stencilRef = this.stencilRef; + data.stencilFuncMask = this.stencilFuncMask; + data.stencilFail = this.stencilFail; + data.stencilZFail = this.stencilZFail; + data.stencilZPass = this.stencilZPass; // rotation (SpriteMaterial) + + if (this.rotation && this.rotation !== 0) data.rotation = this.rotation; + if (this.polygonOffset === true) data.polygonOffset = true; + if (this.polygonOffsetFactor !== 0) data.polygonOffsetFactor = this.polygonOffsetFactor; + if (this.polygonOffsetUnits !== 0) data.polygonOffsetUnits = this.polygonOffsetUnits; + if (this.linewidth && this.linewidth !== 1) data.linewidth = this.linewidth; + if (this.dashSize !== undefined) data.dashSize = this.dashSize; + if (this.gapSize !== undefined) data.gapSize = this.gapSize; + if (this.scale !== undefined) data.scale = this.scale; + if (this.dithering === true) data.dithering = true; + if (this.alphaTest > 0) data.alphaTest = this.alphaTest; + if (this.premultipliedAlpha === true) data.premultipliedAlpha = this.premultipliedAlpha; + if (this.wireframe === true) data.wireframe = this.wireframe; + if (this.wireframeLinewidth > 1) data.wireframeLinewidth = this.wireframeLinewidth; + if (this.wireframeLinecap !== 'round') data.wireframeLinecap = this.wireframeLinecap; + if (this.wireframeLinejoin !== 'round') data.wireframeLinejoin = this.wireframeLinejoin; + if (this.morphTargets === true) data.morphTargets = true; + if (this.morphNormals === true) data.morphNormals = true; + if (this.skinning === true) data.skinning = true; + if (this.visible === false) data.visible = false; + if (this.toneMapped === false) data.toneMapped = false; + if (JSON.stringify(this.userData) !== '{}') data.userData = this.userData; // TODO: Copied from Object3D.toJSON + + function extractFromCache(cache) { + var values = []; + + for (var key in cache) { + var _data = cache[key]; + delete _data.metadata; + values.push(_data); + } - if ( this.w > v.w ) { + return values; + } - this.w = v.w; + if (isRoot) { + var textures = extractFromCache(meta.textures); + var images = extractFromCache(meta.images); + if (textures.length > 0) data.textures = textures; + if (images.length > 0) data.images = images; + } - } + return data; + }, + clone: function clone() { + return new this.constructor().copy(this); + }, + copy: function copy(source) { + this.name = source.name; + this.fog = source.fog; + this.blending = source.blending; + this.side = source.side; + this.flatShading = source.flatShading; + this.vertexColors = source.vertexColors; + this.opacity = source.opacity; + this.transparent = source.transparent; + this.blendSrc = source.blendSrc; + this.blendDst = source.blendDst; + this.blendEquation = source.blendEquation; + this.blendSrcAlpha = source.blendSrcAlpha; + this.blendDstAlpha = source.blendDstAlpha; + this.blendEquationAlpha = source.blendEquationAlpha; + this.depthFunc = source.depthFunc; + this.depthTest = source.depthTest; + this.depthWrite = source.depthWrite; + this.stencilWriteMask = source.stencilWriteMask; + this.stencilFunc = source.stencilFunc; + this.stencilRef = source.stencilRef; + this.stencilFuncMask = source.stencilFuncMask; + this.stencilFail = source.stencilFail; + this.stencilZFail = source.stencilZFail; + this.stencilZPass = source.stencilZPass; + this.stencilWrite = source.stencilWrite; + var srcPlanes = source.clippingPlanes; + var dstPlanes = null; + + if (srcPlanes !== null) { + var n = srcPlanes.length; + dstPlanes = new Array(n); + + for (var i = 0; i !== n; ++i) { + dstPlanes[i] = srcPlanes[i].clone(); + } + } - return this; + this.clippingPlanes = dstPlanes; + this.clipIntersection = source.clipIntersection; + this.clipShadows = source.clipShadows; + this.shadowSide = source.shadowSide; + this.colorWrite = source.colorWrite; + this.precision = source.precision; + this.polygonOffset = source.polygonOffset; + this.polygonOffsetFactor = source.polygonOffsetFactor; + this.polygonOffsetUnits = source.polygonOffsetUnits; + this.dithering = source.dithering; + this.alphaTest = source.alphaTest; + this.premultipliedAlpha = source.premultipliedAlpha; + this.visible = source.visible; + this.toneMapped = source.toneMapped; + this.userData = JSON.parse(JSON.stringify(source.userData)); + return this; + }, + dispose: function dispose() { + this.dispatchEvent({ + type: 'dispose' + }); + } + }); + Object.defineProperty(Material.prototype, 'needsUpdate', { + set: function set(value) { + if (value === true) this.version++; + } + }); - }, + /** + * parameters = { + * color: , + * opacity: , + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), + * combine: THREE.Multiply, + * reflectivity: , + * refractionRatio: , + * + * depthTest: , + * depthWrite: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: + * } + */ - max: function ( v ) { + function MeshBasicMaterial(parameters) { + Material.call(this); + this.type = 'MeshBasicMaterial'; + this.color = new Color(0xffffff); // emissive + + this.map = null; + this.lightMap = null; + this.lightMapIntensity = 1.0; + this.aoMap = null; + this.aoMapIntensity = 1.0; + this.specularMap = null; + this.alphaMap = null; + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + this.skinning = false; + this.morphTargets = false; + this.setValues(parameters); + } + + MeshBasicMaterial.prototype = Object.create(Material.prototype); + MeshBasicMaterial.prototype.constructor = MeshBasicMaterial; + MeshBasicMaterial.prototype.isMeshBasicMaterial = true; + + MeshBasicMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.color.copy(source.color); + this.map = source.map; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + this.specularMap = source.specularMap; + this.alphaMap = source.alphaMap; + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + return this; + }; - if ( this.x < v.x ) { + var _vector$3 = new Vector3(); - this.x = v.x; + var _vector2$1 = new Vector2(); + function BufferAttribute(array, itemSize, normalized) { + if (Array.isArray(array)) { + throw new TypeError('THREE.BufferAttribute: array should be a Typed Array.'); } - if ( this.y < v.y ) { - - this.y = v.y; + this.name = ''; + this.array = array; + this.itemSize = itemSize; + this.count = array !== undefined ? array.length / itemSize : 0; + this.normalized = normalized === true; + this.usage = StaticDrawUsage; + this.updateRange = { + offset: 0, + count: -1 + }; + this.version = 0; + } + Object.defineProperty(BufferAttribute.prototype, 'needsUpdate', { + set: function set(value) { + if (value === true) this.version++; } + }); + Object.assign(BufferAttribute.prototype, { + isBufferAttribute: true, + onUploadCallback: function onUploadCallback() {}, + setUsage: function setUsage(value) { + this.usage = value; + return this; + }, + copy: function copy(source) { + this.name = source.name; + this.array = new source.array.constructor(source.array); + this.itemSize = source.itemSize; + this.count = source.count; + this.normalized = source.normalized; + this.usage = source.usage; + return this; + }, + copyAt: function copyAt(index1, attribute, index2) { + index1 *= this.itemSize; + index2 *= attribute.itemSize; - if ( this.z < v.z ) { + for (var i = 0, l = this.itemSize; i < l; i++) { + this.array[index1 + i] = attribute.array[index2 + i]; + } - this.z = v.z; + return this; + }, + copyArray: function copyArray(array) { + this.array.set(array); + return this; + }, + copyColorsArray: function copyColorsArray(colors) { + var array = this.array; + var offset = 0; - } + for (var i = 0, l = colors.length; i < l; i++) { + var color = colors[i]; - if ( this.w < v.w ) { + if (color === undefined) { + console.warn('THREE.BufferAttribute.copyColorsArray(): color is undefined', i); + color = new Color(); + } - this.w = v.w; + array[offset++] = color.r; + array[offset++] = color.g; + array[offset++] = color.b; + } - } + return this; + }, + copyVector2sArray: function copyVector2sArray(vectors) { + var array = this.array; + var offset = 0; - return this; + for (var i = 0, l = vectors.length; i < l; i++) { + var vector = vectors[i]; - }, + if (vector === undefined) { + console.warn('THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i); + vector = new Vector2(); + } - clamp: function ( min, max ) { - - // This function assumes min < max, if this assumption isn't true it will not operate correctly - - if ( this.x < min.x ) { - - this.x = min.x; - - } else if ( this.x > max.x ) { - - this.x = max.x; - - } - - if ( this.y < min.y ) { + array[offset++] = vector.x; + array[offset++] = vector.y; + } - this.y = min.y; + return this; + }, + copyVector3sArray: function copyVector3sArray(vectors) { + var array = this.array; + var offset = 0; - } else if ( this.y > max.y ) { + for (var i = 0, l = vectors.length; i < l; i++) { + var vector = vectors[i]; - this.y = max.y; + if (vector === undefined) { + console.warn('THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i); + vector = new Vector3(); + } - } + array[offset++] = vector.x; + array[offset++] = vector.y; + array[offset++] = vector.z; + } - if ( this.z < min.z ) { + return this; + }, + copyVector4sArray: function copyVector4sArray(vectors) { + var array = this.array; + var offset = 0; - this.z = min.z; + for (var i = 0, l = vectors.length; i < l; i++) { + var vector = vectors[i]; - } else if ( this.z > max.z ) { + if (vector === undefined) { + console.warn('THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i); + vector = new Vector4(); + } - this.z = max.z; + array[offset++] = vector.x; + array[offset++] = vector.y; + array[offset++] = vector.z; + array[offset++] = vector.w; + } - } + return this; + }, + applyMatrix3: function applyMatrix3(m) { + if (this.itemSize === 2) { + for (var i = 0, l = this.count; i < l; i++) { + _vector2$1.fromBufferAttribute(this, i); - if ( this.w < min.w ) { + _vector2$1.applyMatrix3(m); - this.w = min.w; + this.setXY(i, _vector2$1.x, _vector2$1.y); + } + } else if (this.itemSize === 3) { + for (var _i = 0, _l = this.count; _i < _l; _i++) { + _vector$3.fromBufferAttribute(this, _i); - } else if ( this.w > max.w ) { + _vector$3.applyMatrix3(m); - this.w = max.w; + this.setXYZ(_i, _vector$3.x, _vector$3.y, _vector$3.z); + } + } - } + return this; + }, + applyMatrix4: function applyMatrix4(m) { + for (var i = 0, l = this.count; i < l; i++) { + _vector$3.x = this.getX(i); + _vector$3.y = this.getY(i); + _vector$3.z = this.getZ(i); - return this; + _vector$3.applyMatrix4(m); - }, + this.setXYZ(i, _vector$3.x, _vector$3.y, _vector$3.z); + } - clampScalar: ( function () { + return this; + }, + applyNormalMatrix: function applyNormalMatrix(m) { + for (var i = 0, l = this.count; i < l; i++) { + _vector$3.x = this.getX(i); + _vector$3.y = this.getY(i); + _vector$3.z = this.getZ(i); - var min, max; + _vector$3.applyNormalMatrix(m); - return function ( minVal, maxVal ) { + this.setXYZ(i, _vector$3.x, _vector$3.y, _vector$3.z); + } - if ( min === undefined ) { + return this; + }, + transformDirection: function transformDirection(m) { + for (var i = 0, l = this.count; i < l; i++) { + _vector$3.x = this.getX(i); + _vector$3.y = this.getY(i); + _vector$3.z = this.getZ(i); - min = new THREE.Vector4(); - max = new THREE.Vector4(); + _vector$3.transformDirection(m); + this.setXYZ(i, _vector$3.x, _vector$3.y, _vector$3.z); } - min.set( minVal, minVal, minVal, minVal ); - max.set( maxVal, maxVal, maxVal, maxVal ); + return this; + }, + set: function set(value, offset) { + if (offset === undefined) offset = 0; + this.array.set(value, offset); + return this; + }, + getX: function getX(index) { + return this.array[index * this.itemSize]; + }, + setX: function setX(index, x) { + this.array[index * this.itemSize] = x; + return this; + }, + getY: function getY(index) { + return this.array[index * this.itemSize + 1]; + }, + setY: function setY(index, y) { + this.array[index * this.itemSize + 1] = y; + return this; + }, + getZ: function getZ(index) { + return this.array[index * this.itemSize + 2]; + }, + setZ: function setZ(index, z) { + this.array[index * this.itemSize + 2] = z; + return this; + }, + getW: function getW(index) { + return this.array[index * this.itemSize + 3]; + }, + setW: function setW(index, w) { + this.array[index * this.itemSize + 3] = w; + return this; + }, + setXY: function setXY(index, x, y) { + index *= this.itemSize; + this.array[index + 0] = x; + this.array[index + 1] = y; + return this; + }, + setXYZ: function setXYZ(index, x, y, z) { + index *= this.itemSize; + this.array[index + 0] = x; + this.array[index + 1] = y; + this.array[index + 2] = z; + return this; + }, + setXYZW: function setXYZW(index, x, y, z, w) { + index *= this.itemSize; + this.array[index + 0] = x; + this.array[index + 1] = y; + this.array[index + 2] = z; + this.array[index + 3] = w; + return this; + }, + onUpload: function onUpload(callback) { + this.onUploadCallback = callback; + return this; + }, + clone: function clone() { + return new this.constructor(this.array, this.itemSize).copy(this); + }, + toJSON: function toJSON() { + return { + itemSize: this.itemSize, + type: this.array.constructor.name, + array: Array.prototype.slice.call(this.array), + normalized: this.normalized + }; + } + }); // - return this.clamp( min, max ); + function Int8BufferAttribute(array, itemSize, normalized) { + BufferAttribute.call(this, new Int8Array(array), itemSize, normalized); + } - }; + Int8BufferAttribute.prototype = Object.create(BufferAttribute.prototype); + Int8BufferAttribute.prototype.constructor = Int8BufferAttribute; - } )(), + function Uint8BufferAttribute(array, itemSize, normalized) { + BufferAttribute.call(this, new Uint8Array(array), itemSize, normalized); + } - floor: function () { + Uint8BufferAttribute.prototype = Object.create(BufferAttribute.prototype); + Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute; - this.x = Math.floor( this.x ); - this.y = Math.floor( this.y ); - this.z = Math.floor( this.z ); - this.w = Math.floor( this.w ); + function Uint8ClampedBufferAttribute(array, itemSize, normalized) { + BufferAttribute.call(this, new Uint8ClampedArray(array), itemSize, normalized); + } - return this; + Uint8ClampedBufferAttribute.prototype = Object.create(BufferAttribute.prototype); + Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute; - }, + function Int16BufferAttribute(array, itemSize, normalized) { + BufferAttribute.call(this, new Int16Array(array), itemSize, normalized); + } - ceil: function () { + Int16BufferAttribute.prototype = Object.create(BufferAttribute.prototype); + Int16BufferAttribute.prototype.constructor = Int16BufferAttribute; - this.x = Math.ceil( this.x ); - this.y = Math.ceil( this.y ); - this.z = Math.ceil( this.z ); - this.w = Math.ceil( this.w ); + function Uint16BufferAttribute(array, itemSize, normalized) { + BufferAttribute.call(this, new Uint16Array(array), itemSize, normalized); + } - return this; + Uint16BufferAttribute.prototype = Object.create(BufferAttribute.prototype); + Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute; - }, + function Int32BufferAttribute(array, itemSize, normalized) { + BufferAttribute.call(this, new Int32Array(array), itemSize, normalized); + } - round: function () { + Int32BufferAttribute.prototype = Object.create(BufferAttribute.prototype); + Int32BufferAttribute.prototype.constructor = Int32BufferAttribute; - this.x = Math.round( this.x ); - this.y = Math.round( this.y ); - this.z = Math.round( this.z ); - this.w = Math.round( this.w ); + function Uint32BufferAttribute(array, itemSize, normalized) { + BufferAttribute.call(this, new Uint32Array(array), itemSize, normalized); + } - return this; + Uint32BufferAttribute.prototype = Object.create(BufferAttribute.prototype); + Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute; - }, + function Float32BufferAttribute(array, itemSize, normalized) { + BufferAttribute.call(this, new Float32Array(array), itemSize, normalized); + } - roundToZero: function () { + Float32BufferAttribute.prototype = Object.create(BufferAttribute.prototype); + Float32BufferAttribute.prototype.constructor = Float32BufferAttribute; - 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.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); + function Float64BufferAttribute(array, itemSize, normalized) { + BufferAttribute.call(this, new Float64Array(array), itemSize, normalized); + } - return this; + Float64BufferAttribute.prototype = Object.create(BufferAttribute.prototype); + Float64BufferAttribute.prototype.constructor = Float64BufferAttribute; // - }, + var DirectGeometry = /*#__PURE__*/function () { + function DirectGeometry() { + this.vertices = []; + this.normals = []; + this.colors = []; + this.uvs = []; + this.uvs2 = []; + this.groups = []; + this.morphTargets = {}; + this.skinWeights = []; + this.skinIndices = []; // this.lineDistances = []; - negate: function () { + this.boundingBox = null; + this.boundingSphere = null; // update flags - return this.multiplyScalar( -1 ); + this.verticesNeedUpdate = false; + this.normalsNeedUpdate = false; + this.colorsNeedUpdate = false; + this.uvsNeedUpdate = false; + this.groupsNeedUpdate = false; + } - }, + var _proto = DirectGeometry.prototype; - dot: function ( v ) { + _proto.computeGroups = function computeGroups(geometry) { + var groups = []; + var group, i; + var materialIndex = undefined; + var faces = geometry.faces; - return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; + for (i = 0; i < faces.length; i++) { + var face = faces[i]; // materials - }, + if (face.materialIndex !== materialIndex) { + materialIndex = face.materialIndex; - lengthSq: function () { + if (group !== undefined) { + group.count = i * 3 - group.start; + groups.push(group); + } - return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; + group = { + start: i * 3, + materialIndex: materialIndex + }; + } + } - }, + if (group !== undefined) { + group.count = i * 3 - group.start; + groups.push(group); + } - length: function () { + this.groups = groups; + }; - return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); + _proto.fromGeometry = function fromGeometry(geometry) { + var faces = geometry.faces; + var vertices = geometry.vertices; + var faceVertexUvs = geometry.faceVertexUvs; + var hasFaceVertexUv = faceVertexUvs[0] && faceVertexUvs[0].length > 0; + var hasFaceVertexUv2 = faceVertexUvs[1] && faceVertexUvs[1].length > 0; // morphs + + var morphTargets = geometry.morphTargets; + var morphTargetsLength = morphTargets.length; + var morphTargetsPosition; + + if (morphTargetsLength > 0) { + morphTargetsPosition = []; + + for (var i = 0; i < morphTargetsLength; i++) { + morphTargetsPosition[i] = { + name: morphTargets[i].name, + data: [] + }; + } - }, + this.morphTargets.position = morphTargetsPosition; + } - lengthManhattan: function () { + var morphNormals = geometry.morphNormals; + var morphNormalsLength = morphNormals.length; + var morphTargetsNormal; - return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); + if (morphNormalsLength > 0) { + morphTargetsNormal = []; - }, + for (var _i = 0; _i < morphNormalsLength; _i++) { + morphTargetsNormal[_i] = { + name: morphNormals[_i].name, + data: [] + }; + } - normalize: function () { + this.morphTargets.normal = morphTargetsNormal; + } // skins - return this.divideScalar( this.length() ); - }, + var skinIndices = geometry.skinIndices; + var skinWeights = geometry.skinWeights; + var hasSkinIndices = skinIndices.length === vertices.length; + var hasSkinWeights = skinWeights.length === vertices.length; // - setLength: function ( l ) { + if (vertices.length > 0 && faces.length === 0) { + console.error('THREE.DirectGeometry: Faceless geometries are not supported.'); + } - var oldLength = this.length(); + for (var _i2 = 0; _i2 < faces.length; _i2++) { + var face = faces[_i2]; + this.vertices.push(vertices[face.a], vertices[face.b], vertices[face.c]); + var vertexNormals = face.vertexNormals; - if ( oldLength !== 0 && l !== oldLength ) { + if (vertexNormals.length === 3) { + this.normals.push(vertexNormals[0], vertexNormals[1], vertexNormals[2]); + } else { + var normal = face.normal; + this.normals.push(normal, normal, normal); + } - this.multiplyScalar( l / oldLength ); + var vertexColors = face.vertexColors; - } + if (vertexColors.length === 3) { + this.colors.push(vertexColors[0], vertexColors[1], vertexColors[2]); + } else { + var color = face.color; + this.colors.push(color, color, color); + } - return this; + if (hasFaceVertexUv === true) { + var vertexUvs = faceVertexUvs[0][_i2]; - }, + if (vertexUvs !== undefined) { + this.uvs.push(vertexUvs[0], vertexUvs[1], vertexUvs[2]); + } else { + console.warn('THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', _i2); + this.uvs.push(new Vector2(), new Vector2(), new Vector2()); + } + } - lerp: function ( v, alpha ) { + if (hasFaceVertexUv2 === true) { + var _vertexUvs = faceVertexUvs[1][_i2]; - this.x += ( v.x - this.x ) * alpha; - this.y += ( v.y - this.y ) * alpha; - this.z += ( v.z - this.z ) * alpha; - this.w += ( v.w - this.w ) * alpha; + if (_vertexUvs !== undefined) { + this.uvs2.push(_vertexUvs[0], _vertexUvs[1], _vertexUvs[2]); + } else { + console.warn('THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', _i2); + this.uvs2.push(new Vector2(), new Vector2(), new Vector2()); + } + } // morphs - return this; - }, + for (var j = 0; j < morphTargetsLength; j++) { + var morphTarget = morphTargets[j].vertices; + morphTargetsPosition[j].data.push(morphTarget[face.a], morphTarget[face.b], morphTarget[face.c]); + } - equals: function ( v ) { + for (var _j = 0; _j < morphNormalsLength; _j++) { + var morphNormal = morphNormals[_j].vertexNormals[_i2]; - return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); + morphTargetsNormal[_j].data.push(morphNormal.a, morphNormal.b, morphNormal.c); + } // skins - }, - fromArray: function ( array ) { + if (hasSkinIndices) { + this.skinIndices.push(skinIndices[face.a], skinIndices[face.b], skinIndices[face.c]); + } - this.x = array[ 0 ]; - this.y = array[ 1 ]; - this.z = array[ 2 ]; - this.w = array[ 3 ]; + if (hasSkinWeights) { + this.skinWeights.push(skinWeights[face.a], skinWeights[face.b], skinWeights[face.c]); + } + } - return this; + this.computeGroups(geometry); + this.verticesNeedUpdate = geometry.verticesNeedUpdate; + this.normalsNeedUpdate = geometry.normalsNeedUpdate; + this.colorsNeedUpdate = geometry.colorsNeedUpdate; + this.uvsNeedUpdate = geometry.uvsNeedUpdate; + this.groupsNeedUpdate = geometry.groupsNeedUpdate; - }, + if (geometry.boundingSphere !== null) { + this.boundingSphere = geometry.boundingSphere.clone(); + } - toArray: function () { + if (geometry.boundingBox !== null) { + this.boundingBox = geometry.boundingBox.clone(); + } - return [ this.x, this.y, this.z, this.w ]; + return this; + }; - }, + return DirectGeometry; + }(); - clone: function () { + function arrayMax(array) { + if (array.length === 0) return -Infinity; + var max = array[0]; - return new THREE.Vector4( this.x, this.y, this.z, this.w ); + for (var i = 1, l = array.length; i < l; ++i) { + if (array[i] > max) max = array[i]; + } + return max; } -}; + var _bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id -/** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - * @author bhouston / http://exocortex.com - */ + var _m1$2 = new Matrix4(); -THREE.Euler = function ( x, y, z, order ) { + var _obj = new Object3D(); - this._x = x || 0; - this._y = y || 0; - this._z = z || 0; - this._order = order || THREE.Euler.DefaultOrder; + var _offset = new Vector3(); -}; + var _box$2 = new Box3(); -THREE.Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]; + var _boxMorphTargets = new Box3(); -THREE.Euler.DefaultOrder = 'XYZ'; + var _vector$4 = new Vector3(); -THREE.Euler.prototype = { - - constructor: THREE.Euler, + function BufferGeometry() { + Object.defineProperty(this, 'id', { + value: _bufferGeometryId += 2 + }); + this.uuid = MathUtils.generateUUID(); + this.name = ''; + this.type = 'BufferGeometry'; + this.index = null; + this.attributes = {}; + this.morphAttributes = {}; + this.morphTargetsRelative = false; + this.groups = []; + this.boundingBox = null; + this.boundingSphere = null; + this.drawRange = { + start: 0, + count: Infinity + }; + this.userData = {}; + } - _x: 0, _y: 0, _z: 0, _order: THREE.Euler.DefaultOrder, + BufferGeometry.prototype = Object.assign(Object.create(EventDispatcher.prototype), { + constructor: BufferGeometry, + isBufferGeometry: true, + getIndex: function getIndex() { + return this.index; + }, + setIndex: function setIndex(index) { + if (Array.isArray(index)) { + this.index = new (arrayMax(index) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1); + } else { + this.index = index; + } - get x () { + return this; + }, + getAttribute: function getAttribute(name) { + return this.attributes[name]; + }, + setAttribute: function setAttribute(name, attribute) { + this.attributes[name] = attribute; + return this; + }, + deleteAttribute: function deleteAttribute(name) { + delete this.attributes[name]; + return this; + }, + addGroup: function addGroup(start, count, materialIndex) { + this.groups.push({ + start: start, + count: count, + materialIndex: materialIndex !== undefined ? materialIndex : 0 + }); + }, + clearGroups: function clearGroups() { + this.groups = []; + }, + setDrawRange: function setDrawRange(start, count) { + this.drawRange.start = start; + this.drawRange.count = count; + }, + applyMatrix4: function applyMatrix4(matrix) { + var position = this.attributes.position; - return this._x; + if (position !== undefined) { + position.applyMatrix4(matrix); + position.needsUpdate = true; + } - }, + var normal = this.attributes.normal; - set x ( value ) { + if (normal !== undefined) { + var normalMatrix = new Matrix3().getNormalMatrix(matrix); + normal.applyNormalMatrix(normalMatrix); + normal.needsUpdate = true; + } - this._x = value; - this.onChangeCallback(); + var tangent = this.attributes.tangent; - }, + if (tangent !== undefined) { + tangent.transformDirection(matrix); + tangent.needsUpdate = true; + } - get y () { + if (this.boundingBox !== null) { + this.computeBoundingBox(); + } - return this._y; + if (this.boundingSphere !== null) { + this.computeBoundingSphere(); + } - }, + return this; + }, + rotateX: function rotateX(angle) { + // rotate geometry around world x-axis + _m1$2.makeRotationX(angle); - set y ( value ) { + this.applyMatrix4(_m1$2); + return this; + }, + rotateY: function rotateY(angle) { + // rotate geometry around world y-axis + _m1$2.makeRotationY(angle); - this._y = value; - this.onChangeCallback(); + this.applyMatrix4(_m1$2); + return this; + }, + rotateZ: function rotateZ(angle) { + // rotate geometry around world z-axis + _m1$2.makeRotationZ(angle); - }, + this.applyMatrix4(_m1$2); + return this; + }, + translate: function translate(x, y, z) { + // translate geometry + _m1$2.makeTranslation(x, y, z); - get z () { + this.applyMatrix4(_m1$2); + return this; + }, + scale: function scale(x, y, z) { + // scale geometry + _m1$2.makeScale(x, y, z); - return this._z; + this.applyMatrix4(_m1$2); + return this; + }, + lookAt: function lookAt(vector) { + _obj.lookAt(vector); - }, + _obj.updateMatrix(); - set z ( value ) { + this.applyMatrix4(_obj.matrix); + return this; + }, + center: function center() { + this.computeBoundingBox(); + this.boundingBox.getCenter(_offset).negate(); + this.translate(_offset.x, _offset.y, _offset.z); + return this; + }, + setFromObject: function setFromObject(object) { + // console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this ); + var geometry = object.geometry; - this._z = value; - this.onChangeCallback(); + if (object.isPoints || object.isLine) { + var positions = new Float32BufferAttribute(geometry.vertices.length * 3, 3); + var colors = new Float32BufferAttribute(geometry.colors.length * 3, 3); + this.setAttribute('position', positions.copyVector3sArray(geometry.vertices)); + this.setAttribute('color', colors.copyColorsArray(geometry.colors)); - }, + if (geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length) { + var lineDistances = new Float32BufferAttribute(geometry.lineDistances.length, 1); + this.setAttribute('lineDistance', lineDistances.copyArray(geometry.lineDistances)); + } - get order () { + if (geometry.boundingSphere !== null) { + this.boundingSphere = geometry.boundingSphere.clone(); + } - return this._order; + if (geometry.boundingBox !== null) { + this.boundingBox = geometry.boundingBox.clone(); + } + } else if (object.isMesh) { + if (geometry && geometry.isGeometry) { + this.fromGeometry(geometry); + } + } - }, + return this; + }, + setFromPoints: function setFromPoints(points) { + var position = []; - set order ( value ) { + for (var i = 0, l = points.length; i < l; i++) { + var point = points[i]; + position.push(point.x, point.y, point.z || 0); + } - this._order = value; - this.onChangeCallback(); + this.setAttribute('position', new Float32BufferAttribute(position, 3)); + return this; + }, + updateFromObject: function updateFromObject(object) { + var geometry = object.geometry; - }, + if (object.isMesh) { + var direct = geometry.__directGeometry; - set: function ( x, y, z, order ) { + if (geometry.elementsNeedUpdate === true) { + direct = undefined; + geometry.elementsNeedUpdate = false; + } - this._x = x; - this._y = y; - this._z = z; - this._order = order || this._order; + if (direct === undefined) { + return this.fromGeometry(geometry); + } - this.onChangeCallback(); + direct.verticesNeedUpdate = geometry.verticesNeedUpdate; + direct.normalsNeedUpdate = geometry.normalsNeedUpdate; + direct.colorsNeedUpdate = geometry.colorsNeedUpdate; + direct.uvsNeedUpdate = geometry.uvsNeedUpdate; + direct.groupsNeedUpdate = geometry.groupsNeedUpdate; + geometry.verticesNeedUpdate = false; + geometry.normalsNeedUpdate = false; + geometry.colorsNeedUpdate = false; + geometry.uvsNeedUpdate = false; + geometry.groupsNeedUpdate = false; + geometry = direct; + } - return this; + if (geometry.verticesNeedUpdate === true) { + var attribute = this.attributes.position; - }, + if (attribute !== undefined) { + attribute.copyVector3sArray(geometry.vertices); + attribute.needsUpdate = true; + } - copy: function ( euler ) { + geometry.verticesNeedUpdate = false; + } - this._x = euler._x; - this._y = euler._y; - this._z = euler._z; - this._order = euler._order; + if (geometry.normalsNeedUpdate === true) { + var _attribute = this.attributes.normal; - this.onChangeCallback(); + if (_attribute !== undefined) { + _attribute.copyVector3sArray(geometry.normals); - return this; + _attribute.needsUpdate = true; + } - }, + geometry.normalsNeedUpdate = false; + } - setFromRotationMatrix: function ( m, order ) { + if (geometry.colorsNeedUpdate === true) { + var _attribute2 = this.attributes.color; - var clamp = THREE.Math.clamp; + if (_attribute2 !== undefined) { + _attribute2.copyColorsArray(geometry.colors); - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + _attribute2.needsUpdate = true; + } - var te = m.elements; - var m11 = te[0], m12 = te[4], m13 = te[8]; - var m21 = te[1], m22 = te[5], m23 = te[9]; - var m31 = te[2], m32 = te[6], m33 = te[10]; + geometry.colorsNeedUpdate = false; + } - order = order || this._order; + if (geometry.uvsNeedUpdate) { + var _attribute3 = this.attributes.uv; - if ( order === 'XYZ' ) { + if (_attribute3 !== undefined) { + _attribute3.copyVector2sArray(geometry.uvs); - this._y = Math.asin( clamp( m13, -1, 1 ) ); + _attribute3.needsUpdate = true; + } - if ( Math.abs( m13 ) < 0.99999 ) { + geometry.uvsNeedUpdate = false; + } - this._x = Math.atan2( - m23, m33 ); - this._z = Math.atan2( - m12, m11 ); + if (geometry.lineDistancesNeedUpdate) { + var _attribute4 = this.attributes.lineDistance; - } else { + if (_attribute4 !== undefined) { + _attribute4.copyArray(geometry.lineDistances); - this._x = Math.atan2( m32, m22 ); - this._z = 0; + _attribute4.needsUpdate = true; + } + geometry.lineDistancesNeedUpdate = false; } - } else if ( order === 'YXZ' ) { - - this._x = Math.asin( - clamp( m23, -1, 1 ) ); - - if ( Math.abs( m23 ) < 0.99999 ) { + if (geometry.groupsNeedUpdate) { + geometry.computeGroups(object.geometry); + this.groups = geometry.groups; + geometry.groupsNeedUpdate = false; + } - this._y = Math.atan2( m13, m33 ); - this._z = Math.atan2( m21, m22 ); + return this; + }, + fromGeometry: function fromGeometry(geometry) { + geometry.__directGeometry = new DirectGeometry().fromGeometry(geometry); + return this.fromDirectGeometry(geometry.__directGeometry); + }, + fromDirectGeometry: function fromDirectGeometry(geometry) { + var positions = new Float32Array(geometry.vertices.length * 3); + this.setAttribute('position', new BufferAttribute(positions, 3).copyVector3sArray(geometry.vertices)); - } else { + if (geometry.normals.length > 0) { + var normals = new Float32Array(geometry.normals.length * 3); + this.setAttribute('normal', new BufferAttribute(normals, 3).copyVector3sArray(geometry.normals)); + } - this._y = Math.atan2( - m31, m11 ); - this._z = 0; + if (geometry.colors.length > 0) { + var colors = new Float32Array(geometry.colors.length * 3); + this.setAttribute('color', new BufferAttribute(colors, 3).copyColorsArray(geometry.colors)); + } + if (geometry.uvs.length > 0) { + var uvs = new Float32Array(geometry.uvs.length * 2); + this.setAttribute('uv', new BufferAttribute(uvs, 2).copyVector2sArray(geometry.uvs)); } - } else if ( order === 'ZXY' ) { + if (geometry.uvs2.length > 0) { + var uvs2 = new Float32Array(geometry.uvs2.length * 2); + this.setAttribute('uv2', new BufferAttribute(uvs2, 2).copyVector2sArray(geometry.uvs2)); + } // groups - this._x = Math.asin( clamp( m32, -1, 1 ) ); - if ( Math.abs( m32 ) < 0.99999 ) { + this.groups = geometry.groups; // morphs - this._y = Math.atan2( - m31, m33 ); - this._z = Math.atan2( - m12, m22 ); + for (var name in geometry.morphTargets) { + var array = []; + var morphTargets = geometry.morphTargets[name]; - } else { + for (var i = 0, l = morphTargets.length; i < l; i++) { + var morphTarget = morphTargets[i]; + var attribute = new Float32BufferAttribute(morphTarget.data.length * 3, 3); + attribute.name = morphTarget.name; + array.push(attribute.copyVector3sArray(morphTarget.data)); + } + + this.morphAttributes[name] = array; + } // skinning - this._y = 0; - this._z = Math.atan2( m21, m11 ); + if (geometry.skinIndices.length > 0) { + var skinIndices = new Float32BufferAttribute(geometry.skinIndices.length * 4, 4); + this.setAttribute('skinIndex', skinIndices.copyVector4sArray(geometry.skinIndices)); } - } else if ( order === 'ZYX' ) { + if (geometry.skinWeights.length > 0) { + var skinWeights = new Float32BufferAttribute(geometry.skinWeights.length * 4, 4); + this.setAttribute('skinWeight', skinWeights.copyVector4sArray(geometry.skinWeights)); + } // - this._y = Math.asin( - clamp( m31, -1, 1 ) ); - if ( Math.abs( m31 ) < 0.99999 ) { + if (geometry.boundingSphere !== null) { + this.boundingSphere = geometry.boundingSphere.clone(); + } - this._x = Math.atan2( m32, m33 ); - this._z = Math.atan2( m21, m11 ); + if (geometry.boundingBox !== null) { + this.boundingBox = geometry.boundingBox.clone(); + } - } else { + return this; + }, + computeBoundingBox: function computeBoundingBox() { + if (this.boundingBox === null) { + this.boundingBox = new Box3(); + } - this._x = 0; - this._z = Math.atan2( - m12, m22 ); + var position = this.attributes.position; + var morphAttributesPosition = this.morphAttributes.position; + if (position && position.isGLBufferAttribute) { + console.error('THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box. Alternatively set "mesh.frustumCulled" to "false".', this); + this.boundingBox.set(new Vector3(-Infinity, -Infinity, -Infinity), new Vector3(+Infinity, +Infinity, +Infinity)); + return; } - } else if ( order === 'YZX' ) { + if (position !== undefined) { + this.boundingBox.setFromBufferAttribute(position); // process morph attributes if present - this._z = Math.asin( clamp( m21, -1, 1 ) ); + if (morphAttributesPosition) { + for (var i = 0, il = morphAttributesPosition.length; i < il; i++) { + var morphAttribute = morphAttributesPosition[i]; - if ( Math.abs( m21 ) < 0.99999 ) { + _box$2.setFromBufferAttribute(morphAttribute); - this._x = Math.atan2( - m23, m22 ); - this._y = Math.atan2( - m31, m11 ); + if (this.morphTargetsRelative) { + _vector$4.addVectors(this.boundingBox.min, _box$2.min); - } else { + this.boundingBox.expandByPoint(_vector$4); - this._x = 0; - this._y = Math.atan2( m13, m33 ); + _vector$4.addVectors(this.boundingBox.max, _box$2.max); + this.boundingBox.expandByPoint(_vector$4); + } else { + this.boundingBox.expandByPoint(_box$2.min); + this.boundingBox.expandByPoint(_box$2.max); + } + } + } + } else { + this.boundingBox.makeEmpty(); } - } else if ( order === 'XZY' ) { + if (isNaN(this.boundingBox.min.x) || isNaN(this.boundingBox.min.y) || isNaN(this.boundingBox.min.z)) { + console.error('THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this); + } + }, + computeBoundingSphere: function computeBoundingSphere() { + if (this.boundingSphere === null) { + this.boundingSphere = new Sphere(); + } - this._z = Math.asin( - clamp( m12, -1, 1 ) ); + var position = this.attributes.position; + var morphAttributesPosition = this.morphAttributes.position; - if ( Math.abs( m12 ) < 0.99999 ) { + if (position && position.isGLBufferAttribute) { + console.error('THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere. Alternatively set "mesh.frustumCulled" to "false".', this); + this.boundingSphere.set(new Vector3(), Infinity); + return; + } - this._x = Math.atan2( m32, m22 ); - this._y = Math.atan2( m13, m11 ); + if (position) { + // first, find the center of the bounding sphere + var center = this.boundingSphere.center; - } else { + _box$2.setFromBufferAttribute(position); // process morph attributes if present - this._x = Math.atan2( - m23, m33 ); - this._y = 0; - } + if (morphAttributesPosition) { + for (var i = 0, il = morphAttributesPosition.length; i < il; i++) { + var morphAttribute = morphAttributesPosition[i]; - } else { + _boxMorphTargets.setFromBufferAttribute(morphAttribute); - console.warn( 'WARNING: Euler.setFromRotationMatrix() given unsupported order: ' + order ) + if (this.morphTargetsRelative) { + _vector$4.addVectors(_box$2.min, _boxMorphTargets.min); - } + _box$2.expandByPoint(_vector$4); - this._order = order; + _vector$4.addVectors(_box$2.max, _boxMorphTargets.max); - this.onChangeCallback(); + _box$2.expandByPoint(_vector$4); + } else { + _box$2.expandByPoint(_boxMorphTargets.min); - return this; + _box$2.expandByPoint(_boxMorphTargets.max); + } + } + } - }, + _box$2.getCenter(center); // second, try to find a boundingSphere with a radius smaller than the + // boundingSphere of the boundingBox: sqrt(3) smaller in the best case - setFromQuaternion: function ( q, order, update ) { - var clamp = THREE.Math.clamp; + var maxRadiusSq = 0; - // q is assumed to be normalized + for (var _i = 0, _il = position.count; _i < _il; _i++) { + _vector$4.fromBufferAttribute(position, _i); - // http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m + maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$4)); + } // process morph attributes if present - var sqx = q.x * q.x; - var sqy = q.y * q.y; - var sqz = q.z * q.z; - var sqw = q.w * q.w; - order = order || this._order; + if (morphAttributesPosition) { + for (var _i2 = 0, _il2 = morphAttributesPosition.length; _i2 < _il2; _i2++) { + var _morphAttribute = morphAttributesPosition[_i2]; + var morphTargetsRelative = this.morphTargetsRelative; - if ( order === 'XYZ' ) { + for (var j = 0, jl = _morphAttribute.count; j < jl; j++) { + _vector$4.fromBufferAttribute(_morphAttribute, j); - this._x = Math.atan2( 2 * ( q.x * q.w - q.y * q.z ), ( sqw - sqx - sqy + sqz ) ); - this._y = Math.asin( clamp( 2 * ( q.x * q.z + q.y * q.w ), -1, 1 ) ); - this._z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw + sqx - sqy - sqz ) ); + if (morphTargetsRelative) { + _offset.fromBufferAttribute(position, j); - } else if ( order === 'YXZ' ) { + _vector$4.add(_offset); + } - this._x = Math.asin( clamp( 2 * ( q.x * q.w - q.y * q.z ), -1, 1 ) ); - this._y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw - sqx - sqy + sqz ) ); - this._z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw - sqx + sqy - sqz ) ); + maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$4)); + } + } + } - } else if ( order === 'ZXY' ) { + this.boundingSphere.radius = Math.sqrt(maxRadiusSq); - this._x = Math.asin( clamp( 2 * ( q.x * q.w + q.y * q.z ), -1, 1 ) ); - this._y = Math.atan2( 2 * ( q.y * q.w - q.z * q.x ), ( sqw - sqx - sqy + sqz ) ); - this._z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw - sqx + sqy - sqz ) ); + if (isNaN(this.boundingSphere.radius)) { + console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this); + } + } + }, + computeFaceNormals: function computeFaceNormals() {// backwards compatibility + }, + computeVertexNormals: function computeVertexNormals() { + var index = this.index; + var positionAttribute = this.getAttribute('position'); - } else if ( order === 'ZYX' ) { + if (positionAttribute !== undefined) { + var normalAttribute = this.getAttribute('normal'); - this._x = Math.atan2( 2 * ( q.x * q.w + q.z * q.y ), ( sqw - sqx - sqy + sqz ) ); - this._y = Math.asin( clamp( 2 * ( q.y * q.w - q.x * q.z ), -1, 1 ) ); - this._z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw + sqx - sqy - sqz ) ); + if (normalAttribute === undefined) { + normalAttribute = new BufferAttribute(new Float32Array(positionAttribute.count * 3), 3); + this.setAttribute('normal', normalAttribute); + } else { + // reset existing normals to zero + for (var i = 0, il = normalAttribute.count; i < il; i++) { + normalAttribute.setXYZ(i, 0, 0, 0); + } + } - } else if ( order === 'YZX' ) { + var pA = new Vector3(), + pB = new Vector3(), + pC = new Vector3(); + var nA = new Vector3(), + nB = new Vector3(), + nC = new Vector3(); + var cb = new Vector3(), + ab = new Vector3(); // indexed elements + + if (index) { + for (var _i3 = 0, _il3 = index.count; _i3 < _il3; _i3 += 3) { + var vA = index.getX(_i3 + 0); + var vB = index.getX(_i3 + 1); + var vC = index.getX(_i3 + 2); + pA.fromBufferAttribute(positionAttribute, vA); + pB.fromBufferAttribute(positionAttribute, vB); + pC.fromBufferAttribute(positionAttribute, vC); + cb.subVectors(pC, pB); + ab.subVectors(pA, pB); + cb.cross(ab); + nA.fromBufferAttribute(normalAttribute, vA); + nB.fromBufferAttribute(normalAttribute, vB); + nC.fromBufferAttribute(normalAttribute, vC); + nA.add(cb); + nB.add(cb); + nC.add(cb); + normalAttribute.setXYZ(vA, nA.x, nA.y, nA.z); + normalAttribute.setXYZ(vB, nB.x, nB.y, nB.z); + normalAttribute.setXYZ(vC, nC.x, nC.y, nC.z); + } + } else { + // non-indexed elements (unconnected triangle soup) + for (var _i4 = 0, _il4 = positionAttribute.count; _i4 < _il4; _i4 += 3) { + pA.fromBufferAttribute(positionAttribute, _i4 + 0); + pB.fromBufferAttribute(positionAttribute, _i4 + 1); + pC.fromBufferAttribute(positionAttribute, _i4 + 2); + cb.subVectors(pC, pB); + ab.subVectors(pA, pB); + cb.cross(ab); + normalAttribute.setXYZ(_i4 + 0, cb.x, cb.y, cb.z); + normalAttribute.setXYZ(_i4 + 1, cb.x, cb.y, cb.z); + normalAttribute.setXYZ(_i4 + 2, cb.x, cb.y, cb.z); + } + } - this._x = Math.atan2( 2 * ( q.x * q.w - q.z * q.y ), ( sqw - sqx + sqy - sqz ) ); - this._y = Math.atan2( 2 * ( q.y * q.w - q.x * q.z ), ( sqw + sqx - sqy - sqz ) ); - this._z = Math.asin( clamp( 2 * ( q.x * q.y + q.z * q.w ), -1, 1 ) ); + this.normalizeNormals(); + normalAttribute.needsUpdate = true; + } + }, + merge: function merge(geometry, offset) { + if (!(geometry && geometry.isBufferGeometry)) { + console.error('THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry); + return; + } - } else if ( order === 'XZY' ) { + if (offset === undefined) { + offset = 0; + console.warn('THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.'); + } - this._x = Math.atan2( 2 * ( q.x * q.w + q.y * q.z ), ( sqw - sqx + sqy - sqz ) ); - this._y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw + sqx - sqy - sqz ) ); - this._z = Math.asin( clamp( 2 * ( q.z * q.w - q.x * q.y ), -1, 1 ) ); + var attributes = this.attributes; - } else { + for (var key in attributes) { + if (geometry.attributes[key] === undefined) continue; + var attribute1 = attributes[key]; + var attributeArray1 = attribute1.array; + var attribute2 = geometry.attributes[key]; + var attributeArray2 = attribute2.array; + var attributeOffset = attribute2.itemSize * offset; + var length = Math.min(attributeArray2.length, attributeArray1.length - attributeOffset); - console.warn( 'WARNING: Euler.setFromQuaternion() given unsupported order: ' + order ) + for (var i = 0, j = attributeOffset; i < length; i++, j++) { + attributeArray1[j] = attributeArray2[i]; + } + } - } + return this; + }, + normalizeNormals: function normalizeNormals() { + var normals = this.attributes.normal; - this._order = order; + for (var i = 0, il = normals.count; i < il; i++) { + _vector$4.fromBufferAttribute(normals, i); - if ( update !== false ) this.onChangeCallback(); + _vector$4.normalize(); - return this; + normals.setXYZ(i, _vector$4.x, _vector$4.y, _vector$4.z); + } + }, + toNonIndexed: function toNonIndexed() { + function convertBufferAttribute(attribute, indices) { + var array = attribute.array; + var itemSize = attribute.itemSize; + var normalized = attribute.normalized; + var array2 = new array.constructor(indices.length * itemSize); + var index = 0, + index2 = 0; + + for (var i = 0, l = indices.length; i < l; i++) { + index = indices[i] * itemSize; + + for (var j = 0; j < itemSize; j++) { + array2[index2++] = array[index++]; + } + } - }, + return new BufferAttribute(array2, itemSize, normalized); + } // - reorder: function () { - // WARNING: this discards revolution information -bhouston + if (this.index === null) { + console.warn('THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.'); + return this; + } - var q = new THREE.Quaternion(); + var geometry2 = new BufferGeometry(); + var indices = this.index.array; + var attributes = this.attributes; // attributes - return function ( newOrder ) { + for (var name in attributes) { + var attribute = attributes[name]; + var newAttribute = convertBufferAttribute(attribute, indices); + geometry2.setAttribute(name, newAttribute); + } // morph attributes - q.setFromEuler( this ); - this.setFromQuaternion( q, newOrder ); - }; + var morphAttributes = this.morphAttributes; + for (var _name in morphAttributes) { + var morphArray = []; + var morphAttribute = morphAttributes[_name]; // morphAttribute: array of Float32BufferAttributes - }(), + for (var i = 0, il = morphAttribute.length; i < il; i++) { + var _attribute5 = morphAttribute[i]; - equals: function ( euler ) { + var _newAttribute = convertBufferAttribute(_attribute5, indices); - return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); + morphArray.push(_newAttribute); + } - }, + geometry2.morphAttributes[_name] = morphArray; + } - fromArray: function ( array ) { + geometry2.morphTargetsRelative = this.morphTargetsRelative; // groups - this._x = array[ 0 ]; - this._y = array[ 1 ]; - this._z = array[ 2 ]; - if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; + var groups = this.groups; - this.onChangeCallback(); + for (var _i5 = 0, l = groups.length; _i5 < l; _i5++) { + var group = groups[_i5]; + geometry2.addGroup(group.start, group.count, group.materialIndex); + } - return this; + return geometry2; + }, + toJSON: function toJSON() { + var data = { + metadata: { + version: 4.5, + type: 'BufferGeometry', + generator: 'BufferGeometry.toJSON' + } + }; // standard BufferGeometry serialization - }, + data.uuid = this.uuid; + data.type = this.type; + if (this.name !== '') data.name = this.name; + if (Object.keys(this.userData).length > 0) data.userData = this.userData; - toArray: function () { + if (this.parameters !== undefined) { + var parameters = this.parameters; - return [ this._x, this._y, this._z, this._order ]; + for (var key in parameters) { + if (parameters[key] !== undefined) data[key] = parameters[key]; + } - }, + return data; + } - onChange: function ( callback ) { - - this.onChangeCallback = callback; - - return this; + data.data = { + attributes: {} + }; + var index = this.index; - }, + if (index !== null) { + data.data.index = { + type: index.array.constructor.name, + array: Array.prototype.slice.call(index.array) + }; + } - onChangeCallback: function () {}, + var attributes = this.attributes; - clone: function () { + for (var _key in attributes) { + var attribute = attributes[_key]; + var attributeData = attribute.toJSON(data.data); + if (attribute.name !== '') attributeData.name = attribute.name; + data.data.attributes[_key] = attributeData; + } - return new THREE.Euler( this._x, this._y, this._z, this._order ); + var morphAttributes = {}; + var hasMorphAttributes = false; - } + for (var _key2 in this.morphAttributes) { + var attributeArray = this.morphAttributes[_key2]; + var array = []; -}; + for (var i = 0, il = attributeArray.length; i < il; i++) { + var _attribute6 = attributeArray[i]; -/** - * @author bhouston / http://exocortex.com - */ + var _attributeData = _attribute6.toJSON(data.data); -THREE.Line3 = function ( start, end ) { + if (_attribute6.name !== '') _attributeData.name = _attribute6.name; + array.push(_attributeData); + } - this.start = ( start !== undefined ) ? start : new THREE.Vector3(); - this.end = ( end !== undefined ) ? end : new THREE.Vector3(); + if (array.length > 0) { + morphAttributes[_key2] = array; + hasMorphAttributes = true; + } + } -}; + if (hasMorphAttributes) { + data.data.morphAttributes = morphAttributes; + data.data.morphTargetsRelative = this.morphTargetsRelative; + } -THREE.Line3.prototype = { + var groups = this.groups; - constructor: THREE.Line3, + if (groups.length > 0) { + data.data.groups = JSON.parse(JSON.stringify(groups)); + } - set: function ( start, end ) { + var boundingSphere = this.boundingSphere; - this.start.copy( start ); - this.end.copy( end ); + if (boundingSphere !== null) { + data.data.boundingSphere = { + center: boundingSphere.center.toArray(), + radius: boundingSphere.radius + }; + } - return this; + return data; + }, + clone: function clone() { + /* + // Handle primitives + const parameters = this.parameters; + if ( parameters !== undefined ) { + const values = []; + for ( const key in parameters ) { + values.push( parameters[ key ] ); + } + const geometry = Object.create( this.constructor.prototype ); + this.constructor.apply( geometry, values ); + return geometry; + } + return new this.constructor().copy( this ); + */ + return new BufferGeometry().copy(this); + }, + copy: function copy(source) { + // reset + this.index = null; + this.attributes = {}; + this.morphAttributes = {}; + this.groups = []; + this.boundingBox = null; + this.boundingSphere = null; // used for storing cloned, shared data - }, + var data = {}; // name - copy: function ( line ) { + this.name = source.name; // index - this.start.copy( line.start ); - this.end.copy( line.end ); + var index = source.index; - return this; + if (index !== null) { + this.setIndex(index.clone(data)); + } // attributes - }, - center: function ( optionalTarget ) { + var attributes = source.attributes; - var result = optionalTarget || new THREE.Vector3(); - return result.addVectors( this.start, this.end ).multiplyScalar( 0.5 ); + for (var name in attributes) { + var attribute = attributes[name]; + this.setAttribute(name, attribute.clone(data)); + } // morph attributes - }, - delta: function ( optionalTarget ) { + var morphAttributes = source.morphAttributes; - var result = optionalTarget || new THREE.Vector3(); - return result.subVectors( this.end, this.start ); + for (var _name2 in morphAttributes) { + var array = []; + var morphAttribute = morphAttributes[_name2]; // morphAttribute: array of Float32BufferAttributes - }, + for (var i = 0, l = morphAttribute.length; i < l; i++) { + array.push(morphAttribute[i].clone(data)); + } - distanceSq: function () { + this.morphAttributes[_name2] = array; + } - return this.start.distanceToSquared( this.end ); + this.morphTargetsRelative = source.morphTargetsRelative; // groups - }, + var groups = source.groups; - distance: function () { + for (var _i6 = 0, _l = groups.length; _i6 < _l; _i6++) { + var group = groups[_i6]; + this.addGroup(group.start, group.count, group.materialIndex); + } // bounding box - return this.start.distanceTo( this.end ); - }, + var boundingBox = source.boundingBox; - at: function ( t, optionalTarget ) { + if (boundingBox !== null) { + this.boundingBox = boundingBox.clone(); + } // bounding sphere - var result = optionalTarget || new THREE.Vector3(); - return this.delta( result ).multiplyScalar( t ).add( this.start ); + var boundingSphere = source.boundingSphere; - }, + if (boundingSphere !== null) { + this.boundingSphere = boundingSphere.clone(); + } // draw range - closestPointToPointParameter: function() { - var startP = new THREE.Vector3(); - var startEnd = new THREE.Vector3(); + this.drawRange.start = source.drawRange.start; + this.drawRange.count = source.drawRange.count; // user data - return function ( point, clampToLine ) { + this.userData = source.userData; + return this; + }, + dispose: function dispose() { + this.dispatchEvent({ + type: 'dispose' + }); + } + }); - startP.subVectors( point, this.start ); - startEnd.subVectors( this.end, this.start ); + var _inverseMatrix = new Matrix4(); - var startEnd2 = startEnd.dot( startEnd ); - var startEnd_startP = startEnd.dot( startP ); + var _ray = new Ray(); - var t = startEnd_startP / startEnd2; + var _sphere = new Sphere(); - if ( clampToLine ) { + var _vA = new Vector3(); - t = THREE.Math.clamp( t, 0, 1 ); + var _vB = new Vector3(); - } + var _vC = new Vector3(); - return t; + var _tempA = new Vector3(); - }; + var _tempB = new Vector3(); - }(), + var _tempC = new Vector3(); - closestPointToPoint: function ( point, clampToLine, optionalTarget ) { + var _morphA = new Vector3(); - var t = this.closestPointToPointParameter( point, clampToLine ); + var _morphB = new Vector3(); - var result = optionalTarget || new THREE.Vector3(); + var _morphC = new Vector3(); - return this.delta( result ).multiplyScalar( t ).add( this.start ); + var _uvA = new Vector2(); - }, + var _uvB = new Vector2(); - applyMatrix4: function ( matrix ) { + var _uvC = new Vector2(); - this.start.applyMatrix4( matrix ); - this.end.applyMatrix4( matrix ); + var _intersectionPoint = new Vector3(); - return this; + var _intersectionPointWorld = new Vector3(); - }, + function Mesh(geometry, material) { + Object3D.call(this); + this.type = 'Mesh'; + this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); + this.material = material !== undefined ? material : new MeshBasicMaterial(); + this.updateMorphTargets(); + } - equals: function ( line ) { + Mesh.prototype = Object.assign(Object.create(Object3D.prototype), { + constructor: Mesh, + isMesh: true, + copy: function copy(source) { + Object3D.prototype.copy.call(this, source); - return line.start.equals( this.start ) && line.end.equals( this.end ); + if (source.morphTargetInfluences !== undefined) { + this.morphTargetInfluences = source.morphTargetInfluences.slice(); + } - }, + if (source.morphTargetDictionary !== undefined) { + this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary); + } - clone: function () { + this.material = source.material; + this.geometry = source.geometry; + return this; + }, + updateMorphTargets: function updateMorphTargets() { + var geometry = this.geometry; - return new THREE.Line3().copy( this ); + if (geometry.isBufferGeometry) { + var morphAttributes = geometry.morphAttributes; + var keys = Object.keys(morphAttributes); - } + if (keys.length > 0) { + var morphAttribute = morphAttributes[keys[0]]; -}; + if (morphAttribute !== undefined) { + this.morphTargetInfluences = []; + this.morphTargetDictionary = {}; -/** - * @author bhouston / http://exocortex.com - */ + for (var m = 0, ml = morphAttribute.length; m < ml; m++) { + var name = morphAttribute[m].name || String(m); + this.morphTargetInfluences.push(0); + this.morphTargetDictionary[name] = m; + } + } + } + } else { + var morphTargets = geometry.morphTargets; -THREE.Box2 = function ( min, max ) { + if (morphTargets !== undefined && morphTargets.length > 0) { + console.error('THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.'); + } + } + }, + raycast: function raycast(raycaster, intersects) { + var geometry = this.geometry; + var material = this.material; + var matrixWorld = this.matrixWorld; + if (material === undefined) return; // Checking boundingSphere distance to ray - this.min = ( min !== undefined ) ? min : new THREE.Vector2( Infinity, Infinity ); - this.max = ( max !== undefined ) ? max : new THREE.Vector2( -Infinity, -Infinity ); + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); -}; + _sphere.copy(geometry.boundingSphere); -THREE.Box2.prototype = { + _sphere.applyMatrix4(matrixWorld); - constructor: THREE.Box2, + if (raycaster.ray.intersectsSphere(_sphere) === false) return; // - set: function ( min, max ) { + _inverseMatrix.getInverse(matrixWorld); - this.min.copy( min ); - this.max.copy( max ); + _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix); // Check boundingBox before continuing - return this; - }, + if (geometry.boundingBox !== null) { + if (_ray.intersectsBox(geometry.boundingBox) === false) return; + } - setFromPoints: function ( points ) { + var intersection; - if ( points.length > 0 ) { + if (geometry.isBufferGeometry) { + var index = geometry.index; + var position = geometry.attributes.position; + var morphPosition = geometry.morphAttributes.position; + var morphTargetsRelative = geometry.morphTargetsRelative; + var uv = geometry.attributes.uv; + var uv2 = geometry.attributes.uv2; + var groups = geometry.groups; + var drawRange = geometry.drawRange; - var point = points[ 0 ]; + if (index !== null) { + // indexed buffer geometry + if (Array.isArray(material)) { + for (var i = 0, il = groups.length; i < il; i++) { + var group = groups[i]; + var groupMaterial = material[group.materialIndex]; + var start = Math.max(group.start, drawRange.start); + var end = Math.min(group.start + group.count, drawRange.start + drawRange.count); - this.min.copy( point ); - this.max.copy( point ); + for (var j = start, jl = end; j < jl; j += 3) { + var a = index.getX(j); + var b = index.getX(j + 1); + var c = index.getX(j + 2); + intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c); - for ( var i = 1, il = points.length; i < il; i ++ ) { + if (intersection) { + intersection.faceIndex = Math.floor(j / 3); // triangle number in indexed buffer semantics - point = points[ i ]; + intersection.face.materialIndex = group.materialIndex; + intersects.push(intersection); + } + } + } + } else { + var _start = Math.max(0, drawRange.start); - if ( point.x < this.min.x ) { + var _end = Math.min(index.count, drawRange.start + drawRange.count); - this.min.x = point.x; + for (var _i = _start, _il = _end; _i < _il; _i += 3) { + var _a = index.getX(_i); - } else if ( point.x > this.max.x ) { + var _b = index.getX(_i + 1); - this.max.x = point.x; + var _c = index.getX(_i + 2); - } + intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, _a, _b, _c); - if ( point.y < this.min.y ) { + if (intersection) { + intersection.faceIndex = Math.floor(_i / 3); // triangle number in indexed buffer semantics - this.min.y = point.y; + intersects.push(intersection); + } + } + } + } else if (position !== undefined) { + // non-indexed buffer geometry + if (Array.isArray(material)) { + for (var _i2 = 0, _il2 = groups.length; _i2 < _il2; _i2++) { + var _group = groups[_i2]; + var _groupMaterial = material[_group.materialIndex]; - } else if ( point.y > this.max.y ) { + var _start2 = Math.max(_group.start, drawRange.start); - this.max.y = point.y; + var _end2 = Math.min(_group.start + _group.count, drawRange.start + drawRange.count); - } + for (var _j = _start2, _jl = _end2; _j < _jl; _j += 3) { + var _a2 = _j; - } + var _b2 = _j + 1; - } else { + var _c2 = _j + 2; - this.makeEmpty(); + intersection = checkBufferGeometryIntersection(this, _groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, _a2, _b2, _c2); - } + if (intersection) { + intersection.faceIndex = Math.floor(_j / 3); // triangle number in non-indexed buffer semantics - return this; + intersection.face.materialIndex = _group.materialIndex; + intersects.push(intersection); + } + } + } + } else { + var _start3 = Math.max(0, drawRange.start); - }, + var _end3 = Math.min(position.count, drawRange.start + drawRange.count); - setFromCenterAndSize: function () { + for (var _i3 = _start3, _il3 = _end3; _i3 < _il3; _i3 += 3) { + var _a3 = _i3; - var v1 = new THREE.Vector2(); + var _b3 = _i3 + 1; - return function ( center, size ) { + var _c3 = _i3 + 2; - var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); - this.min.copy( center ).sub( halfSize ); - this.max.copy( center ).add( halfSize ); + intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, _a3, _b3, _c3); - return this; + if (intersection) { + intersection.faceIndex = Math.floor(_i3 / 3); // triangle number in non-indexed buffer semantics - }; + intersects.push(intersection); + } + } + } + } + } else if (geometry.isGeometry) { + var isMultiMaterial = Array.isArray(material); + var vertices = geometry.vertices; + var faces = geometry.faces; + var uvs; + var faceVertexUvs = geometry.faceVertexUvs[0]; + if (faceVertexUvs.length > 0) uvs = faceVertexUvs; - }(), + for (var f = 0, fl = faces.length; f < fl; f++) { + var face = faces[f]; + var faceMaterial = isMultiMaterial ? material[face.materialIndex] : material; + if (faceMaterial === undefined) continue; + var fvA = vertices[face.a]; + var fvB = vertices[face.b]; + var fvC = vertices[face.c]; + intersection = checkIntersection(this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint); - copy: function ( box ) { + if (intersection) { + if (uvs && uvs[f]) { + var uvs_f = uvs[f]; - this.min.copy( box.min ); - this.max.copy( box.max ); + _uvA.copy(uvs_f[0]); - return this; + _uvB.copy(uvs_f[1]); - }, + _uvC.copy(uvs_f[2]); - makeEmpty: function () { + intersection.uv = Triangle.getUV(_intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2()); + } - this.min.x = this.min.y = Infinity; - this.max.x = this.max.y = -Infinity; + intersection.face = face; + intersection.faceIndex = f; + intersects.push(intersection); + } + } + } + } + }); - return this; + function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) { + var intersect; - }, + if (material.side === BackSide) { + intersect = ray.intersectTriangle(pC, pB, pA, true, point); + } else { + intersect = ray.intersectTriangle(pA, pB, pC, material.side !== DoubleSide, point); + } - empty: function () { + if (intersect === null) return null; - // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes + _intersectionPointWorld.copy(point); - return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ); + _intersectionPointWorld.applyMatrix4(object.matrixWorld); - }, + var distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld); + if (distance < raycaster.near || distance > raycaster.far) return null; + return { + distance: distance, + point: _intersectionPointWorld.clone(), + object: object + }; + } - center: function ( optionalTarget ) { + function checkBufferGeometryIntersection(object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c) { + _vA.fromBufferAttribute(position, a); - var result = optionalTarget || new THREE.Vector2(); - return result.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); + _vB.fromBufferAttribute(position, b); - }, + _vC.fromBufferAttribute(position, c); - size: function ( optionalTarget ) { + var morphInfluences = object.morphTargetInfluences; - var result = optionalTarget || new THREE.Vector2(); - return result.subVectors( this.max, this.min ); + if (material.morphTargets && morphPosition && morphInfluences) { + _morphA.set(0, 0, 0); - }, + _morphB.set(0, 0, 0); - expandByPoint: function ( point ) { + _morphC.set(0, 0, 0); - this.min.min( point ); - this.max.max( point ); + for (var i = 0, il = morphPosition.length; i < il; i++) { + var influence = morphInfluences[i]; + var morphAttribute = morphPosition[i]; + if (influence === 0) continue; - return this; - }, + _tempA.fromBufferAttribute(morphAttribute, a); - expandByVector: function ( vector ) { + _tempB.fromBufferAttribute(morphAttribute, b); - this.min.sub( vector ); - this.max.add( vector ); + _tempC.fromBufferAttribute(morphAttribute, c); - return this; - }, + if (morphTargetsRelative) { + _morphA.addScaledVector(_tempA, influence); - expandByScalar: function ( scalar ) { + _morphB.addScaledVector(_tempB, influence); - this.min.addScalar( -scalar ); - this.max.addScalar( scalar ); + _morphC.addScaledVector(_tempC, influence); + } else { + _morphA.addScaledVector(_tempA.sub(_vA), influence); - return this; - }, + _morphB.addScaledVector(_tempB.sub(_vB), influence); - containsPoint: function ( point ) { + _morphC.addScaledVector(_tempC.sub(_vC), influence); + } + } - if ( point.x < this.min.x || point.x > this.max.x || - point.y < this.min.y || point.y > this.max.y ) { + _vA.add(_morphA); - return false; + _vB.add(_morphB); + _vC.add(_morphC); } - return true; - - }, - - containsBox: function ( box ) { + if (object.isSkinnedMesh) { + object.boneTransform(a, _vA); + object.boneTransform(b, _vB); + object.boneTransform(c, _vC); + } - if ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) && - ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) ) { + var intersection = checkIntersection(object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint); - return true; + if (intersection) { + if (uv) { + _uvA.fromBufferAttribute(uv, a); - } + _uvB.fromBufferAttribute(uv, b); - return false; + _uvC.fromBufferAttribute(uv, c); - }, + intersection.uv = Triangle.getUV(_intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2()); + } - getParameter: function ( point, optionalTarget ) { + if (uv2) { + _uvA.fromBufferAttribute(uv2, a); - // This can potentially have a divide by zero if the box - // has a size dimension of 0. + _uvB.fromBufferAttribute(uv2, b); - var result = optionalTarget || new THREE.Vector2(); + _uvC.fromBufferAttribute(uv2, c); - return result.set( - ( point.x - this.min.x ) / ( this.max.x - this.min.x ), - ( point.y - this.min.y ) / ( this.max.y - this.min.y ) - ); + intersection.uv2 = Triangle.getUV(_intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2()); + } - }, + var face = new Face3(a, b, c); + Triangle.getNormal(_vA, _vB, _vC, face.normal); + intersection.face = face; + } - isIntersectionBox: function ( box ) { + return intersection; + } - // using 6 splitting planes to rule out intersections. + var BoxBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(BoxBufferGeometry, _BufferGeometry); - if ( box.max.x < this.min.x || box.min.x > this.max.x || - box.max.y < this.min.y || box.min.y > this.max.y ) { + function BoxBufferGeometry(width, height, depth, widthSegments, heightSegments, depthSegments) { + var _this; - return false; + if (width === void 0) { + width = 1; + } - } + if (height === void 0) { + height = 1; + } - return true; + if (depth === void 0) { + depth = 1; + } - }, + if (widthSegments === void 0) { + widthSegments = 1; + } - clampPoint: function ( point, optionalTarget ) { + if (heightSegments === void 0) { + heightSegments = 1; + } - var result = optionalTarget || new THREE.Vector2(); - return result.copy( point ).clamp( this.min, this.max ); + if (depthSegments === void 0) { + depthSegments = 1; + } - }, + _this = _BufferGeometry.call(this) || this; + _this.type = 'BoxBufferGeometry'; + _this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; - distanceToPoint: function () { + var scope = _assertThisInitialized(_this); // segments - var v1 = new THREE.Vector2(); - return function ( point ) { + widthSegments = Math.floor(widthSegments); + heightSegments = Math.floor(heightSegments); + depthSegments = Math.floor(depthSegments); // buffers - var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); - return clampedPoint.sub( point ).length(); + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; // helper variables - }; + var numberOfVertices = 0; + var groupStart = 0; // build each side of the box geometry - }(), + buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px - intersect: function ( box ) { + buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1); // nx - this.min.max( box.min ); - this.max.min( box.max ); + buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2); // py - return this; + buildPlane('x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3); // ny - }, + buildPlane('x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4); // pz - union: function ( box ) { + buildPlane('x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5); // nz + // build geometry - this.min.min( box.min ); - this.max.max( box.max ); + _this.setIndex(indices); - return this; + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - }, + _this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - translate: function ( offset ) { + _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - this.min.add( offset ); - this.max.add( offset ); + function buildPlane(u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex) { + var segmentWidth = width / gridX; + var segmentHeight = height / gridY; + var widthHalf = width / 2; + var heightHalf = height / 2; + var depthHalf = depth / 2; + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; + var vertexCounter = 0; + var groupCount = 0; + var vector = new Vector3(); // generate vertices, normals and uvs - return this; + for (var iy = 0; iy < gridY1; iy++) { + var y = iy * segmentHeight - heightHalf; - }, + for (var ix = 0; ix < gridX1; ix++) { + var x = ix * segmentWidth - widthHalf; // set values to correct vector component - equals: function ( box ) { + vector[u] = x * udir; + vector[v] = y * vdir; + vector[w] = depthHalf; // now apply vector to vertex buffer - return box.min.equals( this.min ) && box.max.equals( this.max ); + vertices.push(vector.x, vector.y, vector.z); // set values to correct vector component - }, + vector[u] = 0; + vector[v] = 0; + vector[w] = depth > 0 ? 1 : -1; // now apply vector to normal buffer - clone: function () { + normals.push(vector.x, vector.y, vector.z); // uvs - return new THREE.Box2().copy( this ); + uvs.push(ix / gridX); + uvs.push(1 - iy / gridY); // counters - } + vertexCounter += 1; + } + } // indices + // 1. you need three indices to draw a single face + // 2. a single segment consists of two faces + // 3. so we need to generate six (2*3) indices per segment -}; -/** - * @author bhouston / http://exocortex.com - * @author WestLangley / http://github.com/WestLangley - */ + for (var _iy = 0; _iy < gridY; _iy++) { + for (var _ix = 0; _ix < gridX; _ix++) { + var a = numberOfVertices + _ix + gridX1 * _iy; + var b = numberOfVertices + _ix + gridX1 * (_iy + 1); + var c = numberOfVertices + (_ix + 1) + gridX1 * (_iy + 1); + var d = numberOfVertices + (_ix + 1) + gridX1 * _iy; // faces -THREE.Box3 = function ( min, max ) { + indices.push(a, b, d); + indices.push(b, c, d); // increase counter - this.min = ( min !== undefined ) ? min : new THREE.Vector3( Infinity, Infinity, Infinity ); - this.max = ( max !== undefined ) ? max : new THREE.Vector3( -Infinity, -Infinity, -Infinity ); + groupCount += 6; + } + } // add a group to the geometry. this will ensure multi material support -}; -THREE.Box3.prototype = { + scope.addGroup(groupStart, groupCount, materialIndex); // calculate new start value for groups - constructor: THREE.Box3, + groupStart += groupCount; // update total number of vertices - set: function ( min, max ) { + numberOfVertices += vertexCounter; + } - this.min.copy( min ); - this.max.copy( max ); + return _this; + } - return this; + return BoxBufferGeometry; + }(BufferGeometry); - }, + /** + * Uniform Utilities + */ + function cloneUniforms(src) { + var dst = {}; - addPoint: function ( point ) { + for (var u in src) { + dst[u] = {}; - if ( point.x < this.min.x ) { + for (var p in src[u]) { + var property = src[u][p]; - this.min.x = point.x; + if (property && (property.isColor || property.isMatrix3 || property.isMatrix4 || property.isVector2 || property.isVector3 || property.isVector4 || property.isTexture)) { + dst[u][p] = property.clone(); + } else if (Array.isArray(property)) { + dst[u][p] = property.slice(); + } else { + dst[u][p] = property; + } + } + } - } else if ( point.x > this.max.x ) { + return dst; + } + function mergeUniforms(uniforms) { + var merged = {}; - this.max.x = point.x; + for (var u = 0; u < uniforms.length; u++) { + var tmp = cloneUniforms(uniforms[u]); + for (var p in tmp) { + merged[p] = tmp[p]; + } } - if ( point.y < this.min.y ) { - - this.min.y = point.y; + return merged; + } // Legacy - } else if ( point.y > this.max.y ) { + var UniformsUtils = { + clone: cloneUniforms, + merge: mergeUniforms + }; - this.max.y = point.y; + var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; - } + var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; - if ( point.z < this.min.z ) { + /** + * parameters = { + * defines: { "label" : "value" }, + * uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } }, + * + * fragmentShader: , + * vertexShader: , + * + * wireframe: , + * wireframeLinewidth: , + * + * lights: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - this.min.z = point.z; + function ShaderMaterial(parameters) { + Material.call(this); + this.type = 'ShaderMaterial'; + this.defines = {}; + this.uniforms = {}; + this.vertexShader = default_vertex; + this.fragmentShader = default_fragment; + this.linewidth = 1; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.fog = false; // set to use scene fog - } else if ( point.z > this.max.z ) { + this.lights = false; // set to use scene lights - this.max.z = point.z; + this.clipping = false; // set to use user-defined clipping planes - } - - return this; + this.skinning = false; // set to use skinning attribute streams - }, + this.morphTargets = false; // set to use morph targets - setFromPoints: function ( points ) { + this.morphNormals = false; // set to use morph normals - if ( points.length > 0 ) { + this.extensions = { + derivatives: false, + // set to use derivatives + fragDepth: false, + // set to use fragment depth values + drawBuffers: false, + // set to use draw buffers + shaderTextureLOD: false // set to use shader texture LOD - var point = points[ 0 ]; + }; // When rendered geometry doesn't include these attributes but the material does, + // use these default values in WebGL. This avoids errors when buffer data is missing. - this.min.copy( point ); - this.max.copy( point ); + this.defaultAttributeValues = { + 'color': [1, 1, 1], + 'uv': [0, 0], + 'uv2': [0, 0] + }; + this.index0AttributeName = undefined; + this.uniformsNeedUpdate = false; + this.glslVersion = null; + + if (parameters !== undefined) { + if (parameters.attributes !== undefined) { + console.error('THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.'); + } + + this.setValues(parameters); + } + } + + ShaderMaterial.prototype = Object.create(Material.prototype); + ShaderMaterial.prototype.constructor = ShaderMaterial; + ShaderMaterial.prototype.isShaderMaterial = true; + + ShaderMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.fragmentShader = source.fragmentShader; + this.vertexShader = source.vertexShader; + this.uniforms = cloneUniforms(source.uniforms); + this.defines = Object.assign({}, source.defines); + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.lights = source.lights; + this.clipping = source.clipping; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; + this.extensions = Object.assign({}, source.extensions); + this.glslVersion = source.glslVersion; + return this; + }; - for ( var i = 1, il = points.length; i < il; i ++ ) { + ShaderMaterial.prototype.toJSON = function (meta) { + var data = Material.prototype.toJSON.call(this, meta); + data.glslVersion = this.glslVersion; + data.uniforms = {}; - this.addPoint( points[ i ] ) + for (var name in this.uniforms) { + var uniform = this.uniforms[name]; + var value = uniform.value; + if (value && value.isTexture) { + data.uniforms[name] = { + type: 't', + value: value.toJSON(meta).uuid + }; + } else if (value && value.isColor) { + data.uniforms[name] = { + type: 'c', + value: value.getHex() + }; + } else if (value && value.isVector2) { + data.uniforms[name] = { + type: 'v2', + value: value.toArray() + }; + } else if (value && value.isVector3) { + data.uniforms[name] = { + type: 'v3', + value: value.toArray() + }; + } else if (value && value.isVector4) { + data.uniforms[name] = { + type: 'v4', + value: value.toArray() + }; + } else if (value && value.isMatrix3) { + data.uniforms[name] = { + type: 'm3', + value: value.toArray() + }; + } else if (value && value.isMatrix4) { + data.uniforms[name] = { + type: 'm4', + value: value.toArray() + }; + } else { + data.uniforms[name] = { + value: value + }; // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far } + } - } else { - - this.makeEmpty(); + if (Object.keys(this.defines).length > 0) data.defines = this.defines; + data.vertexShader = this.vertexShader; + data.fragmentShader = this.fragmentShader; + var extensions = {}; + for (var key in this.extensions) { + if (this.extensions[key] === true) extensions[key] = true; } - return this; + if (Object.keys(extensions).length > 0) data.extensions = extensions; + return data; + }; - }, + function Camera() { + Object3D.call(this); + this.type = 'Camera'; + this.matrixWorldInverse = new Matrix4(); + this.projectionMatrix = new Matrix4(); + this.projectionMatrixInverse = new Matrix4(); + } + + Camera.prototype = Object.assign(Object.create(Object3D.prototype), { + constructor: Camera, + isCamera: true, + copy: function copy(source, recursive) { + Object3D.prototype.copy.call(this, source, recursive); + this.matrixWorldInverse.copy(source.matrixWorldInverse); + this.projectionMatrix.copy(source.projectionMatrix); + this.projectionMatrixInverse.copy(source.projectionMatrixInverse); + return this; + }, + getWorldDirection: function getWorldDirection(target) { + if (target === undefined) { + console.warn('THREE.Camera: .getWorldDirection() target is now required'); + target = new Vector3(); + } - setFromCenterAndSize: function() { + this.updateWorldMatrix(true, false); + var e = this.matrixWorld.elements; + return target.set(-e[8], -e[9], -e[10]).normalize(); + }, + updateMatrixWorld: function updateMatrixWorld(force) { + Object3D.prototype.updateMatrixWorld.call(this, force); + this.matrixWorldInverse.getInverse(this.matrixWorld); + }, + updateWorldMatrix: function updateWorldMatrix(updateParents, updateChildren) { + Object3D.prototype.updateWorldMatrix.call(this, updateParents, updateChildren); + this.matrixWorldInverse.getInverse(this.matrixWorld); + }, + clone: function clone() { + return new this.constructor().copy(this); + } + }); + + function PerspectiveCamera(fov, aspect, near, far) { + Camera.call(this); + this.type = 'PerspectiveCamera'; + this.fov = fov !== undefined ? fov : 50; + this.zoom = 1; + this.near = near !== undefined ? near : 0.1; + this.far = far !== undefined ? far : 2000; + this.focus = 10; + this.aspect = aspect !== undefined ? aspect : 1; + this.view = null; + this.filmGauge = 35; // width of the film (default in millimeters) + + this.filmOffset = 0; // horizontal film offset (same unit as gauge) + + this.updateProjectionMatrix(); + } + + PerspectiveCamera.prototype = Object.assign(Object.create(Camera.prototype), { + constructor: PerspectiveCamera, + isPerspectiveCamera: true, + copy: function copy(source, recursive) { + Camera.prototype.copy.call(this, source, recursive); + this.fov = source.fov; + this.zoom = source.zoom; + this.near = source.near; + this.far = source.far; + this.focus = source.focus; + this.aspect = source.aspect; + this.view = source.view === null ? null : Object.assign({}, source.view); + this.filmGauge = source.filmGauge; + this.filmOffset = source.filmOffset; + return this; + }, - var v1 = new THREE.Vector3(); + /** + * Sets the FOV by focal length in respect to the current .filmGauge. + * + * The default film gauge is 35, so that the focal length can be specified for + * a 35mm (full frame) camera. + * + * Values for focal length and film gauge must have the same unit. + */ + setFocalLength: function setFocalLength(focalLength) { + // see http://www.bobatkins.com/photography/technical/field_of_view.html + var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; + this.fov = MathUtils.RAD2DEG * 2 * Math.atan(vExtentSlope); + this.updateProjectionMatrix(); + }, - return function ( center, size ) { + /** + * Calculates the focal length from the current .fov and .filmGauge. + */ + getFocalLength: function getFocalLength() { + var vExtentSlope = Math.tan(MathUtils.DEG2RAD * 0.5 * this.fov); + return 0.5 * this.getFilmHeight() / vExtentSlope; + }, + getEffectiveFOV: function getEffectiveFOV() { + return MathUtils.RAD2DEG * 2 * Math.atan(Math.tan(MathUtils.DEG2RAD * 0.5 * this.fov) / this.zoom); + }, + getFilmWidth: function getFilmWidth() { + // film not completely covered in portrait format (aspect < 1) + return this.filmGauge * Math.min(this.aspect, 1); + }, + getFilmHeight: function getFilmHeight() { + // film not completely covered in landscape format (aspect > 1) + return this.filmGauge / Math.max(this.aspect, 1); + }, - var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); + /** + * Sets an offset in a larger frustum. This is useful for multi-window or + * multi-monitor/multi-machine setups. + * + * For example, if you have 3x2 monitors and each monitor is 1920x1080 and + * the monitors are in grid like this + * + * +---+---+---+ + * | A | B | C | + * +---+---+---+ + * | D | E | F | + * +---+---+---+ + * + * then for each monitor you would call it like this + * + * const w = 1920; + * const h = 1080; + * const fullWidth = w * 3; + * const fullHeight = h * 2; + * + * --A-- + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); + * --B-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); + * --C-- + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); + * --D-- + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); + * --E-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); + * --F-- + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); + * + * Note there is no reason monitors have to be the same size or in a grid. + */ + setViewOffset: function setViewOffset(fullWidth, fullHeight, x, y, width, height) { + this.aspect = fullWidth / fullHeight; + + if (this.view === null) { + this.view = { + enabled: true, + fullWidth: 1, + fullHeight: 1, + offsetX: 0, + offsetY: 0, + width: 1, + height: 1 + }; + } - this.min.copy( center ).sub( halfSize ); - this.max.copy( center ).add( halfSize ); + 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: function clearViewOffset() { + if (this.view !== null) { + this.view.enabled = false; + } - return this; + this.updateProjectionMatrix(); + }, + updateProjectionMatrix: function updateProjectionMatrix() { + var near = this.near; + var top = near * Math.tan(MathUtils.DEG2RAD * 0.5 * this.fov) / this.zoom; + var height = 2 * top; + var width = this.aspect * height; + var left = -0.5 * width; + var view = this.view; + + if (this.view !== null && this.view.enabled) { + var fullWidth = view.fullWidth, + fullHeight = view.fullHeight; + left += view.offsetX * width / fullWidth; + top -= view.offsetY * height / fullHeight; + width *= view.width / fullWidth; + height *= view.height / fullHeight; + } + + var skew = this.filmOffset; + if (skew !== 0) left += near * skew / this.getFilmWidth(); + this.projectionMatrix.makePerspective(left, left + width, top, top - height, near, this.far); + this.projectionMatrixInverse.getInverse(this.projectionMatrix); + }, + toJSON: function toJSON(meta) { + var data = Object3D.prototype.toJSON.call(this, meta); + data.object.fov = this.fov; + data.object.zoom = this.zoom; + data.object.near = this.near; + data.object.far = this.far; + data.object.focus = this.focus; + data.object.aspect = this.aspect; + if (this.view !== null) data.object.view = Object.assign({}, this.view); + data.object.filmGauge = this.filmGauge; + data.object.filmOffset = this.filmOffset; + return data; + } + }); + + var fov = 90, + aspect = 1; + + function CubeCamera(near, far, renderTarget) { + Object3D.call(this); + this.type = 'CubeCamera'; + + if (renderTarget.isWebGLCubeRenderTarget !== true) { + console.error('THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.'); + return; + } + this.renderTarget = renderTarget; + var cameraPX = new PerspectiveCamera(fov, aspect, near, far); + cameraPX.layers = this.layers; + cameraPX.up.set(0, -1, 0); + cameraPX.lookAt(new Vector3(1, 0, 0)); + this.add(cameraPX); + var cameraNX = new PerspectiveCamera(fov, aspect, near, far); + cameraNX.layers = this.layers; + cameraNX.up.set(0, -1, 0); + cameraNX.lookAt(new Vector3(-1, 0, 0)); + this.add(cameraNX); + var cameraPY = new PerspectiveCamera(fov, aspect, near, far); + cameraPY.layers = this.layers; + cameraPY.up.set(0, 0, 1); + cameraPY.lookAt(new Vector3(0, 1, 0)); + this.add(cameraPY); + var cameraNY = new PerspectiveCamera(fov, aspect, near, far); + cameraNY.layers = this.layers; + cameraNY.up.set(0, 0, -1); + cameraNY.lookAt(new Vector3(0, -1, 0)); + this.add(cameraNY); + var cameraPZ = new PerspectiveCamera(fov, aspect, near, far); + cameraPZ.layers = this.layers; + cameraPZ.up.set(0, -1, 0); + cameraPZ.lookAt(new Vector3(0, 0, 1)); + this.add(cameraPZ); + var cameraNZ = new PerspectiveCamera(fov, aspect, near, far); + cameraNZ.layers = this.layers; + cameraNZ.up.set(0, -1, 0); + cameraNZ.lookAt(new Vector3(0, 0, -1)); + this.add(cameraNZ); + + this.update = function (renderer, scene) { + if (this.parent === null) this.updateMatrixWorld(); + var currentXrEnabled = renderer.xr.enabled; + var currentRenderTarget = renderer.getRenderTarget(); + renderer.xr.enabled = false; + var generateMipmaps = renderTarget.texture.generateMipmaps; + renderTarget.texture.generateMipmaps = false; + renderer.setRenderTarget(renderTarget, 0); + renderer.render(scene, cameraPX); + renderer.setRenderTarget(renderTarget, 1); + renderer.render(scene, cameraNX); + renderer.setRenderTarget(renderTarget, 2); + renderer.render(scene, cameraPY); + renderer.setRenderTarget(renderTarget, 3); + renderer.render(scene, cameraNY); + renderer.setRenderTarget(renderTarget, 4); + renderer.render(scene, cameraPZ); + renderTarget.texture.generateMipmaps = generateMipmaps; + renderer.setRenderTarget(renderTarget, 5); + renderer.render(scene, cameraNZ); + renderer.setRenderTarget(currentRenderTarget); + renderer.xr.enabled = currentXrEnabled; }; + } - }(), - - setFromObject: function() { - - // Computes the world-axis-aligned bounding box of an object (including its children), - // accounting for both the object's, and childrens', world transforms + CubeCamera.prototype = Object.create(Object3D.prototype); + CubeCamera.prototype.constructor = CubeCamera; - var v1 = new THREE.Vector3(); + function CubeTexture(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding) { + images = images !== undefined ? images : []; + mapping = mapping !== undefined ? mapping : CubeReflectionMapping; + format = format !== undefined ? format : RGBFormat; + Texture.call(this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); + this.flipY = false; // Why CubeTexture._needsFlipEnvMap is necessary: + // + // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) + // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, + // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. + // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped + // and the flag _needsFlipEnvMap controls this conversion. The flip is not required (and thus _needsFlipEnvMap is set to false) + // when using WebGLCubeRenderTarget.texture as a cube texture. + + this._needsFlipEnvMap = true; + } + + CubeTexture.prototype = Object.create(Texture.prototype); + CubeTexture.prototype.constructor = CubeTexture; + CubeTexture.prototype.isCubeTexture = true; + Object.defineProperty(CubeTexture.prototype, 'images', { + get: function get() { + return this.image; + }, + set: function set(value) { + this.image = value; + } + }); - return function( object ) { + function WebGLCubeRenderTarget(size, options, dummy) { + if (Number.isInteger(options)) { + console.warn('THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )'); + options = dummy; + } - var scope = this; + WebGLRenderTarget.call(this, size, size, options); + options = options || {}; + this.texture = new CubeTexture(undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); + this.texture._needsFlipEnvMap = false; + } - object.updateMatrixWorld( true ); + WebGLCubeRenderTarget.prototype = Object.create(WebGLRenderTarget.prototype); + WebGLCubeRenderTarget.prototype.constructor = WebGLCubeRenderTarget; + WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true; - this.makeEmpty(); + WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function (renderer, texture) { + this.texture.type = texture.type; + this.texture.format = RGBAFormat; // see #18859 - object.traverse( function ( node ) { + this.texture.encoding = texture.encoding; + this.texture.generateMipmaps = texture.generateMipmaps; + this.texture.minFilter = texture.minFilter; + this.texture.magFilter = texture.magFilter; + var shader = { + uniforms: { + tEquirect: { + value: null + } + }, + vertexShader: + /* glsl */ + "\n\n\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t}\n\n\t\t\tvoid main() {\n\n\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t#include \n\t\t\t\t#include \n\n\t\t\t}\n\t\t", + fragmentShader: + /* glsl */ + "\n\n\t\t\tuniform sampler2D tEquirect;\n\n\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t#include \n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t}\n\t\t" + }; + var geometry = new BoxBufferGeometry(5, 5, 5); + var material = new ShaderMaterial({ + name: 'CubemapFromEquirect', + uniforms: cloneUniforms(shader.uniforms), + vertexShader: shader.vertexShader, + fragmentShader: shader.fragmentShader, + side: BackSide, + blending: NoBlending + }); + material.uniforms.tEquirect.value = texture; + var mesh = new Mesh(geometry, material); + var currentMinFilter = texture.minFilter; // Avoid blurred poles + + if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; + var camera = new CubeCamera(1, 10, this); + camera.update(renderer, mesh); + texture.minFilter = currentMinFilter; + mesh.geometry.dispose(); + mesh.material.dispose(); + return this; + }; - if ( node.geometry !== undefined && node.geometry.vertices !== undefined ) { + WebGLCubeRenderTarget.prototype.clear = function (renderer, color, depth, stencil) { + var currentRenderTarget = renderer.getRenderTarget(); - var vertices = node.geometry.vertices; + for (var i = 0; i < 6; i++) { + renderer.setRenderTarget(this, i); + renderer.clear(color, depth, stencil); + } - for ( var i = 0, il = vertices.length; i < il; i++ ) { + renderer.setRenderTarget(currentRenderTarget); + }; - v1.copy( vertices[ i ] ); + function DataTexture(data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding) { + Texture.call(this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); + this.image = { + data: data || null, + width: width || 1, + height: height || 1 + }; + this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; + this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; + this.generateMipmaps = false; + this.flipY = false; + this.unpackAlignment = 1; + this.needsUpdate = true; + } - v1.applyMatrix4( node.matrixWorld ); + DataTexture.prototype = Object.create(Texture.prototype); + DataTexture.prototype.constructor = DataTexture; + DataTexture.prototype.isDataTexture = true; - scope.expandByPoint( v1 ); + var _sphere$1 = /*@__PURE__*/new Sphere(); - } + var _vector$5 = /*@__PURE__*/new Vector3(); - } + var Frustum = /*#__PURE__*/function () { + function Frustum(p0, p1, p2, p3, p4, p5) { + this.planes = [p0 !== undefined ? p0 : new Plane(), p1 !== undefined ? p1 : new Plane(), p2 !== undefined ? p2 : new Plane(), p3 !== undefined ? p3 : new Plane(), p4 !== undefined ? p4 : new Plane(), p5 !== undefined ? p5 : new Plane()]; + } - } ); + var _proto = Frustum.prototype; + _proto.set = function set(p0, p1, p2, p3, p4, p5) { + var planes = this.planes; + planes[0].copy(p0); + planes[1].copy(p1); + planes[2].copy(p2); + planes[3].copy(p3); + planes[4].copy(p4); + planes[5].copy(p5); return this; + }; + _proto.clone = function clone() { + return new this.constructor().copy(this); }; - }(), + _proto.copy = function copy(frustum) { + var planes = this.planes; - copy: function ( box ) { + for (var i = 0; i < 6; i++) { + planes[i].copy(frustum.planes[i]); + } - this.min.copy( box.min ); - this.max.copy( box.max ); + return this; + }; - return this; + _proto.setFromProjectionMatrix = function setFromProjectionMatrix(m) { + var planes = this.planes; + var me = m.elements; + var me0 = me[0], + me1 = me[1], + me2 = me[2], + me3 = me[3]; + var me4 = me[4], + me5 = me[5], + me6 = me[6], + me7 = me[7]; + var me8 = me[8], + me9 = me[9], + me10 = me[10], + me11 = me[11]; + var me12 = me[12], + me13 = me[13], + me14 = me[14], + me15 = me[15]; + planes[0].setComponents(me3 - me0, me7 - me4, me11 - me8, me15 - me12).normalize(); + planes[1].setComponents(me3 + me0, me7 + me4, me11 + me8, me15 + me12).normalize(); + planes[2].setComponents(me3 + me1, me7 + me5, me11 + me9, me15 + me13).normalize(); + planes[3].setComponents(me3 - me1, me7 - me5, me11 - me9, me15 - me13).normalize(); + planes[4].setComponents(me3 - me2, me7 - me6, me11 - me10, me15 - me14).normalize(); + planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize(); + return this; + }; - }, + _proto.intersectsObject = function intersectsObject(object) { + var geometry = object.geometry; + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); - makeEmpty: function () { + _sphere$1.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld); - this.min.x = this.min.y = this.min.z = Infinity; - this.max.x = this.max.y = this.max.z = -Infinity; + return this.intersectsSphere(_sphere$1); + }; - return this; + _proto.intersectsSprite = function intersectsSprite(sprite) { + _sphere$1.center.set(0, 0, 0); - }, + _sphere$1.radius = 0.7071067811865476; - empty: function () { + _sphere$1.applyMatrix4(sprite.matrixWorld); - // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes + return this.intersectsSphere(_sphere$1); + }; - return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); + _proto.intersectsSphere = function intersectsSphere(sphere) { + var planes = this.planes; + var center = sphere.center; + var negRadius = -sphere.radius; - }, + for (var i = 0; i < 6; i++) { + var distance = planes[i].distanceToPoint(center); - center: function ( optionalTarget ) { + if (distance < negRadius) { + return false; + } + } - var result = optionalTarget || new THREE.Vector3(); - return result.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); + return true; + }; - }, + _proto.intersectsBox = function intersectsBox(box) { + var planes = this.planes; - size: function ( optionalTarget ) { + for (var i = 0; i < 6; i++) { + var plane = planes[i]; // corner at max distance - var result = optionalTarget || new THREE.Vector3(); - return result.subVectors( this.max, this.min ); + _vector$5.x = plane.normal.x > 0 ? box.max.x : box.min.x; + _vector$5.y = plane.normal.y > 0 ? box.max.y : box.min.y; + _vector$5.z = plane.normal.z > 0 ? box.max.z : box.min.z; - }, + if (plane.distanceToPoint(_vector$5) < 0) { + return false; + } + } - expandByPoint: function ( point ) { + return true; + }; - this.min.min( point ); - this.max.max( point ); + _proto.containsPoint = function containsPoint(point) { + var planes = this.planes; - return this; + for (var i = 0; i < 6; i++) { + if (planes[i].distanceToPoint(point) < 0) { + return false; + } + } - }, + return true; + }; - expandByVector: function ( vector ) { + return Frustum; + }(); - this.min.sub( vector ); - this.max.add( vector ); + function WebGLAnimation() { + var context = null; + var isAnimating = false; + var animationLoop = null; + var requestId = null; - return this; + function onAnimationFrame(time, frame) { + animationLoop(time, frame); + requestId = context.requestAnimationFrame(onAnimationFrame); + } - }, + return { + start: function start() { + if (isAnimating === true) return; + if (animationLoop === null) return; + requestId = context.requestAnimationFrame(onAnimationFrame); + isAnimating = true; + }, + stop: function stop() { + context.cancelAnimationFrame(requestId); + isAnimating = false; + }, + setAnimationLoop: function setAnimationLoop(callback) { + animationLoop = callback; + }, + setContext: function setContext(value) { + context = value; + } + }; + } - expandByScalar: function ( scalar ) { + function WebGLAttributes(gl, capabilities) { + var isWebGL2 = capabilities.isWebGL2; + var buffers = new WeakMap(); + + function createBuffer(attribute, bufferType) { + var array = attribute.array; + var usage = attribute.usage; + var buffer = gl.createBuffer(); + gl.bindBuffer(bufferType, buffer); + gl.bufferData(bufferType, array, usage); + attribute.onUploadCallback(); + var type = 5126; + + if (array instanceof Float32Array) { + type = 5126; + } else if (array instanceof Float64Array) { + console.warn('THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.'); + } else if (array instanceof Uint16Array) { + type = 5123; + } else if (array instanceof Int16Array) { + type = 5122; + } else if (array instanceof Uint32Array) { + type = 5125; + } else if (array instanceof Int32Array) { + type = 5124; + } else if (array instanceof Int8Array) { + type = 5120; + } else if (array instanceof Uint8Array) { + type = 5121; + } + + return { + buffer: buffer, + type: type, + bytesPerElement: array.BYTES_PER_ELEMENT, + version: attribute.version + }; + } - this.min.addScalar( -scalar ); - this.max.addScalar( scalar ); + function updateBuffer(buffer, attribute, bufferType) { + var array = attribute.array; + var updateRange = attribute.updateRange; + gl.bindBuffer(bufferType, buffer); - return this; + if (updateRange.count === -1) { + // Not using update ranges + gl.bufferSubData(bufferType, 0, array); + } else { + if (isWebGL2) { + gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array, updateRange.offset, updateRange.count); + } else { + gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array.subarray(updateRange.offset, updateRange.offset + updateRange.count)); + } - }, + updateRange.count = -1; // reset range + } + } // - containsPoint: function ( point ) { - if ( point.x < this.min.x || point.x > this.max.x || - point.y < this.min.y || point.y > this.max.y || - point.z < this.min.z || point.z > this.max.z ) { + function get(attribute) { + if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; + return buffers.get(attribute); + } - return false; + function remove(attribute) { + if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; + var data = buffers.get(attribute); + if (data) { + gl.deleteBuffer(data.buffer); + buffers.delete(attribute); + } } - return true; + function update(attribute, bufferType) { + if (attribute.isGLBufferAttribute) { + var cached = buffers.get(attribute); - }, + if (!cached || cached.version < attribute.version) { + buffers.set(attribute, { + buffer: attribute.buffer, + type: attribute.type, + bytesPerElement: attribute.elementSize, + version: attribute.version + }); + } - containsBox: function ( box ) { + return; + } - if ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) && - ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) && - ( this.min.z <= box.min.z ) && ( box.max.z <= this.max.z ) ) { - - return true; + if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; + var data = buffers.get(attribute); + if (data === undefined) { + buffers.set(attribute, createBuffer(attribute, bufferType)); + } else if (data.version < attribute.version) { + updateBuffer(data.buffer, attribute, bufferType); + data.version = attribute.version; + } } - return false; - - }, + return { + get: get, + remove: remove, + update: update + }; + } - getParameter: function ( point, optionalTarget ) { + var PlaneBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(PlaneBufferGeometry, _BufferGeometry); - // This can potentially have a divide by zero if the box - // has a size dimension of 0. + function PlaneBufferGeometry(width, height, widthSegments, heightSegments) { + var _this; - var result = optionalTarget || new THREE.Vector3(); + _this = _BufferGeometry.call(this) || this; + _this.type = 'PlaneBufferGeometry'; + _this.parameters = { + width: width, + height: height, + widthSegments: widthSegments, + heightSegments: heightSegments + }; + width = width || 1; + height = height || 1; + var width_half = width / 2; + var height_half = height / 2; + var gridX = Math.floor(widthSegments) || 1; + var gridY = Math.floor(heightSegments) || 1; + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; + var segment_width = width / gridX; + var segment_height = height / gridY; // buffers + + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; // generate vertices, normals and uvs + + for (var iy = 0; iy < gridY1; iy++) { + var y = iy * segment_height - height_half; + + for (var ix = 0; ix < gridX1; ix++) { + var x = ix * segment_width - width_half; + vertices.push(x, -y, 0); + normals.push(0, 0, 1); + uvs.push(ix / gridX); + uvs.push(1 - iy / gridY); + } + } // indices - return result.set( - ( point.x - this.min.x ) / ( this.max.x - this.min.x ), - ( point.y - this.min.y ) / ( this.max.y - this.min.y ), - ( point.z - this.min.z ) / ( this.max.z - this.min.z ) - ); - }, + for (var _iy = 0; _iy < gridY; _iy++) { + for (var _ix = 0; _ix < gridX; _ix++) { + var a = _ix + gridX1 * _iy; + var b = _ix + gridX1 * (_iy + 1); + var c = _ix + 1 + gridX1 * (_iy + 1); + var d = _ix + 1 + gridX1 * _iy; // faces - isIntersectionBox: function ( box ) { + indices.push(a, b, d); + indices.push(b, c, d); + } + } // build geometry - // using 6 splitting planes to rule out intersections. - if ( box.max.x < this.min.x || box.min.x > this.max.x || - box.max.y < this.min.y || box.min.y > this.max.y || - box.max.z < this.min.z || box.min.z > this.max.z ) { + _this.setIndex(indices); - return false; + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - } + _this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - return true; + _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - }, + return _this; + } - clampPoint: function ( point, optionalTarget ) { + return PlaneBufferGeometry; + }(BufferGeometry); - var result = optionalTarget || new THREE.Vector3(); - return result.copy( point ).clamp( this.min, this.max ); + var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; - }, + var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; - distanceToPoint: function() { + var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif"; - var v1 = new THREE.Vector3(); + var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif"; - return function ( point ) { + var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; - var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); - return clampedPoint.sub( point ).length(); + var begin_vertex = "vec3 transformed = vec3( position );"; - }; + var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; - }(), + var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif"; - getBoundingSphere: function() { + var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif"; - var v1 = new THREE.Vector3(); + var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; - return function ( optionalTarget ) { + var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; - var result = optionalTarget || new THREE.Sphere(); + var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif"; - result.center = this.center(); - result.radius = this.size( v1 ).length() * 0.5; + var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif"; - return result; + var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; - }; + var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; - }(), + var color_pars_vertex = "#if defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvarying vec3 vColor;\n#endif"; - intersect: function ( box ) { + var color_vertex = "#if defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor.xyz *= color.xyz;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif"; - this.min.max( box.min ); - this.max.min( box.max ); + var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}"; - return this; + var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_maxMipLevel 8.0\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_maxTileSize 256.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\tfloat texelSize = 1.0 / ( 3.0 * cubeUV_maxTileSize );\n\t\tvec2 uv = getUV( direction, face ) * ( faceSize - 1.0 );\n\t\tvec2 f = fract( uv );\n\t\tuv += 0.5 - f;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tif ( mipInt < cubeUV_maxMipLevel ) {\n\t\t\tuv.y += 2.0 * cubeUV_maxTileSize;\n\t\t}\n\t\tuv.y += filterInt * 2.0 * cubeUV_minTileSize;\n\t\tuv.x += 3.0 * max( 0.0, cubeUV_maxTileSize - 2.0 * faceSize );\n\t\tuv *= texelSize;\n\t\tvec3 tl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tuv.x += texelSize;\n\t\tvec3 tr = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tuv.y += texelSize;\n\t\tvec3 br = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tuv.x -= texelSize;\n\t\tvec3 bl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tvec3 tm = mix( tl, tr, f.x );\n\t\tvec3 bm = mix( bl, br, f.x );\n\t\treturn mix( tm, bm, f.y );\n\t}\n\t#define r0 1.0\n\t#define v0 0.339\n\t#define m0 - 2.0\n\t#define r1 0.8\n\t#define v1 0.276\n\t#define m1 - 1.0\n\t#define r4 0.4\n\t#define v4 0.046\n\t#define m4 2.0\n\t#define r5 0.305\n\t#define v5 0.016\n\t#define m5 3.0\n\t#define r6 0.21\n\t#define v6 0.0038\n\t#define m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= r1 ) {\n\t\t\tmip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0;\n\t\t} else if ( roughness >= r4 ) {\n\t\t\tmip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1;\n\t\t} else if ( roughness >= r5 ) {\n\t\t\tmip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4;\n\t\t} else if ( roughness >= r6 ) {\n\t\t\tmip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), m0, cubeUV_maxMipLevel );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif"; - }, + var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif"; - union: function ( box ) { + var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; - this.min.min( box.min ); - this.max.max( box.max ); + var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif"; - return this; + var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; - }, - - applyMatrix4: function() { - - var points = [ - new THREE.Vector3(), - new THREE.Vector3(), - new THREE.Vector3(), - new THREE.Vector3(), - new THREE.Vector3(), - new THREE.Vector3(), - new THREE.Vector3(), - new THREE.Vector3() - ]; - - return function ( matrix ) { - - // NOTE: I am using a binary pattern to specify all 2^3 combinations below - points[0].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000 - points[1].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001 - points[2].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010 - points[3].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011 - points[4].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100 - points[5].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101 - points[6].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110 - points[7].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111 + var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; - this.makeEmpty(); - this.setFromPoints( points ); + var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; - return this; + var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = clamp( floor( D ) / 255.0, 0.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}"; - }; + var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\tenvColor = envMapTexelToLinear( envColor );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif"; - }(), + var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif"; - translate: function ( offset ) { + var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif"; - this.min.add( offset ); - this.max.add( offset ); + var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif"; - return this; + var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif"; - }, + var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = - mvPosition.z;\n#endif"; - equals: function ( box ) { + var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif"; - return box.min.equals( this.min ) && box.max.equals( this.max ); + var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; - }, + var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif"; - clone: function () { + var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn texture2D( gradientMap, coord ).rgb;\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}"; - return new THREE.Box3().copy( this ); + var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\treflectedLight.indirectDiffuse += PI * lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n#endif"; - } + var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; -}; + var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\nvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\nvIndirectFront += getLightProbeIrradiance( lightProbe, geometry );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry );\n#endif\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif"; -/** - * @author alteredq / http://alteredqualia.com/ - * @author WestLangley / http://github.com/WestLangley - * @author bhouston / http://exocortex.com - */ + var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif"; -THREE.Matrix3 = function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { + var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif"; - this.elements = new Float32Array( 9 ); + var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;"; - var te = this.elements; + var lights_toon_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct ToonMaterial {\n\tvec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material )\t(0)"; - te[0] = ( n11 !== undefined ) ? n11 : 1; te[3] = n12 || 0; te[6] = n13 || 0; - te[1] = n21 || 0; te[4] = ( n22 !== undefined ) ? n22 : 1; te[7] = n23 || 0; - te[2] = n31 || 0; te[5] = n32 || 0; te[8] = ( n33 !== undefined ) ? n33 : 1; + var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; -}; + var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)"; -THREE.Matrix3.prototype = { + var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.specularRoughness = max( roughnessFactor, 0.0525 );material.specularRoughness += geometryRoughness;\nmaterial.specularRoughness = min( material.specularRoughness, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif"; - constructor: THREE.Matrix3, + var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat specularRoughness;\n\tvec3 specularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}"; - set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { + var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif"; - var te = this.elements; + var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif"; - te[0] = n11; te[3] = n12; te[6] = n13; - te[1] = n21; te[4] = n22; te[7] = n23; - te[2] = n31; te[5] = n32; te[8] = n33; + var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif"; - return this; + var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; - }, + var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif"; - identity: function () { + var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif"; - this.set( + var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif"; - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 + var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif"; - ); + var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; - return this; + var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif"; - }, + var map_particle_pars_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; - copy: function ( m ) { + var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; - var me = m.elements; + var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; - this.set( + var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n#endif"; - me[0], me[3], me[6], - me[1], me[4], me[7], - me[2], me[5], me[8] + var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifndef USE_MORPHNORMALS\n\t\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\t\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; - ); + var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t#endif\n#endif"; - return this; + var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;"; - }, + var normal_fragment_maps = "#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\t#ifdef USE_TANGENT\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, mapN );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif"; - multiplyVector3: function ( vector ) { + var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tmat3 tsn = mat3( S, T, N );\n\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif"; - console.warn( 'DEPRECATED: Matrix3\'s .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); - return vector.applyMatrix3( this ); + var clearcoat_normal_fragment_begin = "#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif"; - }, + var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN );\n\t#endif\n#endif"; - multiplyVector3Array: function ( a ) { + var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif"; - console.warn( 'DEPRECATED: Matrix3\'s .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); - return this.applyToVector3Array( a ); + var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 pack2HalfToRGBA( vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ));\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);\n}\nvec2 unpackRGBATo2Half( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; - }, + var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; - applyToVector3Array: function() { + var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;"; - var v1 = new THREE.Vector3(); + var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; - return function ( array, offset, length ) { + var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; - if ( offset === undefined ) offset = 0; - if ( length === undefined ) length = array.length; + var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; - for ( var i = 0, j = offset, il; i < length; i += 3, j += 3 ) { + var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; - v1.x = array[ j ]; - v1.y = array[ j + 1 ]; - v1.z = array[ j + 2 ]; + var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif"; - v1.applyMatrix3( this ); + var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif"; - array[ j ] = v1.x; - array[ j + 1 ] = v1.y; - array[ j + 2 ] = v1.z; + var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0\n\t\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\tvec4 shadowWorldPosition;\n\t#endif\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif"; - } + var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}"; - return array; + var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; - }; + var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif"; - }(), + var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; - multiplyScalar: function ( s ) { + var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif"; - var te = this.elements; + var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; - 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; + var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; - return this; + var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; - }, + var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }"; - determinant: function () { + var transmissionmap_fragment = "#ifdef USE_TRANSMISSIONMAP\n\ttotalTransmission *= texture2D( transmissionMap, vUv ).r;\n#endif"; - var te = this.elements; + var transmissionmap_pars_fragment = "#ifdef USE_TRANSMISSIONMAP\n\tuniform sampler2D transmissionMap;\n#endif"; - var 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]; + var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif"; - return a*e*i - a*f*h - b*d*i + b*f*g + c*d*h - c*e*g; + var uv_pars_vertex = "#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif"; - }, + var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; - getInverse: function ( matrix, throwOnInvertible ) { + var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; - // input: THREE.Matrix4 - // ( based on http://code.google.com/p/webgl-mjs/ ) + var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif"; - var me = matrix.elements; - var te = this.elements; + var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; - te[ 0 ] = me[10] * me[5] - me[6] * me[9]; - te[ 1 ] = - me[10] * me[1] + me[2] * me[9]; - te[ 2 ] = me[6] * me[1] - me[2] * me[5]; - te[ 3 ] = - me[10] * me[4] + me[6] * me[8]; - te[ 4 ] = me[10] * me[0] - me[2] * me[8]; - te[ 5 ] = - me[6] * me[0] + me[2] * me[4]; - te[ 6 ] = me[9] * me[4] - me[5] * me[8]; - te[ 7 ] = - me[9] * me[0] + me[1] * me[8]; - te[ 8 ] = me[5] * me[0] - me[1] * me[4]; + var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif"; - var det = me[ 0 ] * te[ 0 ] + me[ 1 ] * te[ 3 ] + me[ 2 ] * te[ 6 ]; + var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; - // no inverse + var background_vert = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}"; - if ( det === 0 ) { + var cube_frag = "#include \nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 vReflect = vWorldDirection;\n\t#include \n\tgl_FragColor = envColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}"; - var msg = "Matrix3.getInverse(): can't invert matrix, determinant is 0"; + var cube_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}"; - if ( throwOnInvertible || false ) { + var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}"; - throw new Error( msg ); + var depth_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvHighPrecisionZW = gl_Position.zw;\n}"; - } else { + var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}"; - console.warn( msg ); + var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}"; - } + var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; - this.identity(); + var equirect_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}"; - return this; + var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } + var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - this.multiplyScalar( 1.0 / det ); + var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - return this; + var meshbasic_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - }, + var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - transpose: function () { + var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - var tmp, m = this.elements; + var meshmatcap_frag = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - 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; + var meshmatcap_vert = "#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}"; - return this; + var meshtoon_frag = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - }, + var meshtoon_vert = "#define TOON\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}"; - flattenToArrayOffset: function( array, offset ) { + var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - var te = this.elements; + var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - 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]; + var meshphysical_frag = "#define STANDARD\n#ifdef PHYSICAL\n\t#define REFLECTIVITY\n\t#define CLEARCOAT\n\t#define TRANSMISSION\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef TRANSMISSION\n\tuniform float transmission;\n#endif\n#ifdef REFLECTIVITY\n\tuniform float reflectivity;\n#endif\n#ifdef CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheen;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#ifdef TRANSMISSION\n\t\tfloat totalTransmission = transmission;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSMISSION\n\t\tdiffuseColor.a *= mix( saturate( 1. - totalTransmission + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) ), 1.0, metalness );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - return array; + var meshphysical_vert = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}"; - }, + var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; - getNormalMatrix: function ( m ) { + var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}"; - // input: THREE.Matrix4 + var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - this.getInverse( m ).transpose(); + var points_vert = "uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - return this; + var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n\t#include \n\t#include \n}"; - }, + var shadow_vert = "#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - transposeIntoArray: function ( r ) { + var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}"; - var m = this.elements; + var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; - 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 ]; + var ShaderChunk = { + alphamap_fragment: alphamap_fragment, + alphamap_pars_fragment: alphamap_pars_fragment, + alphatest_fragment: alphatest_fragment, + aomap_fragment: aomap_fragment, + aomap_pars_fragment: aomap_pars_fragment, + begin_vertex: begin_vertex, + beginnormal_vertex: beginnormal_vertex, + bsdfs: bsdfs, + bumpmap_pars_fragment: bumpmap_pars_fragment, + clipping_planes_fragment: clipping_planes_fragment, + clipping_planes_pars_fragment: clipping_planes_pars_fragment, + clipping_planes_pars_vertex: clipping_planes_pars_vertex, + clipping_planes_vertex: clipping_planes_vertex, + color_fragment: color_fragment, + color_pars_fragment: color_pars_fragment, + color_pars_vertex: color_pars_vertex, + color_vertex: color_vertex, + common: common, + cube_uv_reflection_fragment: cube_uv_reflection_fragment, + defaultnormal_vertex: defaultnormal_vertex, + displacementmap_pars_vertex: displacementmap_pars_vertex, + displacementmap_vertex: displacementmap_vertex, + emissivemap_fragment: emissivemap_fragment, + emissivemap_pars_fragment: emissivemap_pars_fragment, + encodings_fragment: encodings_fragment, + encodings_pars_fragment: encodings_pars_fragment, + envmap_fragment: envmap_fragment, + envmap_common_pars_fragment: envmap_common_pars_fragment, + envmap_pars_fragment: envmap_pars_fragment, + envmap_pars_vertex: envmap_pars_vertex, + envmap_physical_pars_fragment: envmap_physical_pars_fragment, + envmap_vertex: envmap_vertex, + fog_vertex: fog_vertex, + fog_pars_vertex: fog_pars_vertex, + fog_fragment: fog_fragment, + fog_pars_fragment: fog_pars_fragment, + gradientmap_pars_fragment: gradientmap_pars_fragment, + lightmap_fragment: lightmap_fragment, + lightmap_pars_fragment: lightmap_pars_fragment, + lights_lambert_vertex: lights_lambert_vertex, + lights_pars_begin: lights_pars_begin, + lights_toon_fragment: lights_toon_fragment, + lights_toon_pars_fragment: lights_toon_pars_fragment, + lights_phong_fragment: lights_phong_fragment, + lights_phong_pars_fragment: lights_phong_pars_fragment, + lights_physical_fragment: lights_physical_fragment, + lights_physical_pars_fragment: lights_physical_pars_fragment, + lights_fragment_begin: lights_fragment_begin, + lights_fragment_maps: lights_fragment_maps, + lights_fragment_end: lights_fragment_end, + logdepthbuf_fragment: logdepthbuf_fragment, + logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, + logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, + logdepthbuf_vertex: logdepthbuf_vertex, + map_fragment: map_fragment, + map_pars_fragment: map_pars_fragment, + map_particle_fragment: map_particle_fragment, + map_particle_pars_fragment: map_particle_pars_fragment, + metalnessmap_fragment: metalnessmap_fragment, + metalnessmap_pars_fragment: metalnessmap_pars_fragment, + morphnormal_vertex: morphnormal_vertex, + morphtarget_pars_vertex: morphtarget_pars_vertex, + morphtarget_vertex: morphtarget_vertex, + normal_fragment_begin: normal_fragment_begin, + normal_fragment_maps: normal_fragment_maps, + normalmap_pars_fragment: normalmap_pars_fragment, + clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin, + clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps, + clearcoat_pars_fragment: clearcoat_pars_fragment, + packing: packing, + premultiplied_alpha_fragment: premultiplied_alpha_fragment, + project_vertex: project_vertex, + dithering_fragment: dithering_fragment, + dithering_pars_fragment: dithering_pars_fragment, + roughnessmap_fragment: roughnessmap_fragment, + roughnessmap_pars_fragment: roughnessmap_pars_fragment, + shadowmap_pars_fragment: shadowmap_pars_fragment, + shadowmap_pars_vertex: shadowmap_pars_vertex, + shadowmap_vertex: shadowmap_vertex, + shadowmask_pars_fragment: shadowmask_pars_fragment, + skinbase_vertex: skinbase_vertex, + skinning_pars_vertex: skinning_pars_vertex, + skinning_vertex: skinning_vertex, + skinnormal_vertex: skinnormal_vertex, + specularmap_fragment: specularmap_fragment, + specularmap_pars_fragment: specularmap_pars_fragment, + tonemapping_fragment: tonemapping_fragment, + tonemapping_pars_fragment: tonemapping_pars_fragment, + transmissionmap_fragment: transmissionmap_fragment, + transmissionmap_pars_fragment: transmissionmap_pars_fragment, + uv_pars_fragment: uv_pars_fragment, + uv_pars_vertex: uv_pars_vertex, + uv_vertex: uv_vertex, + uv2_pars_fragment: uv2_pars_fragment, + uv2_pars_vertex: uv2_pars_vertex, + uv2_vertex: uv2_vertex, + worldpos_vertex: worldpos_vertex, + background_frag: background_frag, + background_vert: background_vert, + cube_frag: cube_frag, + cube_vert: cube_vert, + depth_frag: depth_frag, + depth_vert: depth_vert, + distanceRGBA_frag: distanceRGBA_frag, + distanceRGBA_vert: distanceRGBA_vert, + equirect_frag: equirect_frag, + equirect_vert: equirect_vert, + linedashed_frag: linedashed_frag, + linedashed_vert: linedashed_vert, + meshbasic_frag: meshbasic_frag, + meshbasic_vert: meshbasic_vert, + meshlambert_frag: meshlambert_frag, + meshlambert_vert: meshlambert_vert, + meshmatcap_frag: meshmatcap_frag, + meshmatcap_vert: meshmatcap_vert, + meshtoon_frag: meshtoon_frag, + meshtoon_vert: meshtoon_vert, + meshphong_frag: meshphong_frag, + meshphong_vert: meshphong_vert, + meshphysical_frag: meshphysical_frag, + meshphysical_vert: meshphysical_vert, + normal_frag: normal_frag, + normal_vert: normal_vert, + points_frag: points_frag, + points_vert: points_vert, + shadow_frag: shadow_frag, + shadow_vert: shadow_vert, + sprite_frag: sprite_frag, + sprite_vert: sprite_vert + }; - return this; + /** + * Uniforms library for shared webgl shaders + */ - }, + var UniformsLib = { + common: { + diffuse: { + value: new Color(0xeeeeee) + }, + opacity: { + value: 1.0 + }, + map: { + value: null + }, + uvTransform: { + value: new Matrix3() + }, + uv2Transform: { + value: new Matrix3() + }, + alphaMap: { + value: null + } + }, + specularmap: { + specularMap: { + value: null + } + }, + envmap: { + envMap: { + value: null + }, + flipEnvMap: { + value: -1 + }, + reflectivity: { + value: 1.0 + }, + refractionRatio: { + value: 0.98 + }, + maxMipLevel: { + value: 0 + } + }, + aomap: { + aoMap: { + value: null + }, + aoMapIntensity: { + value: 1 + } + }, + lightmap: { + lightMap: { + value: null + }, + lightMapIntensity: { + value: 1 + } + }, + emissivemap: { + emissiveMap: { + value: null + } + }, + bumpmap: { + bumpMap: { + value: null + }, + bumpScale: { + value: 1 + } + }, + normalmap: { + normalMap: { + value: null + }, + normalScale: { + value: new Vector2(1, 1) + } + }, + displacementmap: { + displacementMap: { + value: null + }, + displacementScale: { + value: 1 + }, + displacementBias: { + value: 0 + } + }, + roughnessmap: { + roughnessMap: { + value: null + } + }, + metalnessmap: { + metalnessMap: { + value: null + } + }, + gradientmap: { + gradientMap: { + value: null + } + }, + fog: { + fogDensity: { + value: 0.00025 + }, + fogNear: { + value: 1 + }, + fogFar: { + value: 2000 + }, + fogColor: { + value: new Color(0xffffff) + } + }, + lights: { + ambientLightColor: { + value: [] + }, + lightProbe: { + value: [] + }, + directionalLights: { + value: [], + properties: { + direction: {}, + color: {} + } + }, + directionalLightShadows: { + value: [], + properties: { + shadowBias: {}, + shadowNormalBias: {}, + shadowRadius: {}, + shadowMapSize: {} + } + }, + directionalShadowMap: { + value: [] + }, + directionalShadowMatrix: { + value: [] + }, + spotLights: { + value: [], + properties: { + color: {}, + position: {}, + direction: {}, + distance: {}, + coneCos: {}, + penumbraCos: {}, + decay: {} + } + }, + spotLightShadows: { + value: [], + properties: { + shadowBias: {}, + shadowNormalBias: {}, + shadowRadius: {}, + shadowMapSize: {} + } + }, + spotShadowMap: { + value: [] + }, + spotShadowMatrix: { + value: [] + }, + pointLights: { + value: [], + properties: { + color: {}, + position: {}, + decay: {}, + distance: {} + } + }, + pointLightShadows: { + value: [], + properties: { + shadowBias: {}, + shadowNormalBias: {}, + shadowRadius: {}, + shadowMapSize: {}, + shadowCameraNear: {}, + shadowCameraFar: {} + } + }, + pointShadowMap: { + value: [] + }, + pointShadowMatrix: { + value: [] + }, + hemisphereLights: { + value: [], + properties: { + direction: {}, + skyColor: {}, + groundColor: {} + } + }, + // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src + rectAreaLights: { + value: [], + properties: { + color: {}, + position: {}, + width: {}, + height: {} + } + }, + ltc_1: { + value: null + }, + ltc_2: { + value: null + } + }, + points: { + diffuse: { + value: new Color(0xeeeeee) + }, + opacity: { + value: 1.0 + }, + size: { + value: 1.0 + }, + scale: { + value: 1.0 + }, + map: { + value: null + }, + alphaMap: { + value: null + }, + uvTransform: { + value: new Matrix3() + } + }, + sprite: { + diffuse: { + value: new Color(0xeeeeee) + }, + opacity: { + value: 1.0 + }, + center: { + value: new Vector2(0.5, 0.5) + }, + rotation: { + value: 0.0 + }, + map: { + value: null + }, + alphaMap: { + value: null + }, + uvTransform: { + value: new Matrix3() + } + } + }; - fromArray: function ( array ) { + var ShaderLib = { + basic: { + uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.fog]), + vertexShader: ShaderChunk.meshbasic_vert, + fragmentShader: ShaderChunk.meshbasic_frag + }, + lambert: { + uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.fog, UniformsLib.lights, { + emissive: { + value: new Color(0x000000) + } + }]), + vertexShader: ShaderChunk.meshlambert_vert, + fragmentShader: ShaderChunk.meshlambert_frag + }, + phong: { + uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, UniformsLib.lights, { + emissive: { + value: new Color(0x000000) + }, + specular: { + value: new Color(0x111111) + }, + shininess: { + value: 30 + } + }]), + vertexShader: ShaderChunk.meshphong_vert, + fragmentShader: ShaderChunk.meshphong_frag + }, + standard: { + uniforms: mergeUniforms([UniformsLib.common, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.roughnessmap, UniformsLib.metalnessmap, UniformsLib.fog, UniformsLib.lights, { + emissive: { + value: new Color(0x000000) + }, + roughness: { + value: 1.0 + }, + metalness: { + value: 0.0 + }, + envMapIntensity: { + value: 1 + } // temporary + + }]), + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag + }, + toon: { + uniforms: mergeUniforms([UniformsLib.common, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.gradientmap, UniformsLib.fog, UniformsLib.lights, { + emissive: { + value: new Color(0x000000) + } + }]), + vertexShader: ShaderChunk.meshtoon_vert, + fragmentShader: ShaderChunk.meshtoon_frag + }, + matcap: { + uniforms: mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, { + matcap: { + value: null + } + }]), + vertexShader: ShaderChunk.meshmatcap_vert, + fragmentShader: ShaderChunk.meshmatcap_frag + }, + points: { + uniforms: mergeUniforms([UniformsLib.points, UniformsLib.fog]), + vertexShader: ShaderChunk.points_vert, + fragmentShader: ShaderChunk.points_frag + }, + dashed: { + uniforms: mergeUniforms([UniformsLib.common, UniformsLib.fog, { + scale: { + value: 1 + }, + dashSize: { + value: 1 + }, + totalSize: { + value: 2 + } + }]), + vertexShader: ShaderChunk.linedashed_vert, + fragmentShader: ShaderChunk.linedashed_frag + }, + depth: { + uniforms: mergeUniforms([UniformsLib.common, UniformsLib.displacementmap]), + vertexShader: ShaderChunk.depth_vert, + fragmentShader: ShaderChunk.depth_frag + }, + normal: { + uniforms: mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, { + opacity: { + value: 1.0 + } + }]), + vertexShader: ShaderChunk.normal_vert, + fragmentShader: ShaderChunk.normal_frag + }, + sprite: { + uniforms: mergeUniforms([UniformsLib.sprite, UniformsLib.fog]), + vertexShader: ShaderChunk.sprite_vert, + fragmentShader: ShaderChunk.sprite_frag + }, + background: { + uniforms: { + uvTransform: { + value: new Matrix3() + }, + t2D: { + value: null + } + }, + vertexShader: ShaderChunk.background_vert, + fragmentShader: ShaderChunk.background_frag + }, - this.elements.set( array ); + /* ------------------------------------------------------------------------- + // Cube map shader + ------------------------------------------------------------------------- */ + cube: { + uniforms: mergeUniforms([UniformsLib.envmap, { + opacity: { + value: 1.0 + } + }]), + vertexShader: ShaderChunk.cube_vert, + fragmentShader: ShaderChunk.cube_frag + }, + equirect: { + uniforms: { + tEquirect: { + value: null + } + }, + vertexShader: ShaderChunk.equirect_vert, + fragmentShader: ShaderChunk.equirect_frag + }, + distanceRGBA: { + uniforms: mergeUniforms([UniformsLib.common, UniformsLib.displacementmap, { + referencePosition: { + value: new Vector3() + }, + nearDistance: { + value: 1 + }, + farDistance: { + value: 1000 + } + }]), + vertexShader: ShaderChunk.distanceRGBA_vert, + fragmentShader: ShaderChunk.distanceRGBA_frag + }, + shadow: { + uniforms: mergeUniforms([UniformsLib.lights, UniformsLib.fog, { + color: { + value: new Color(0x00000) + }, + opacity: { + value: 1.0 + } + }]), + vertexShader: ShaderChunk.shadow_vert, + fragmentShader: ShaderChunk.shadow_frag + } + }; + ShaderLib.physical = { + uniforms: mergeUniforms([ShaderLib.standard.uniforms, { + clearcoat: { + value: 0 + }, + clearcoatMap: { + value: null + }, + clearcoatRoughness: { + value: 0 + }, + clearcoatRoughnessMap: { + value: null + }, + clearcoatNormalScale: { + value: new Vector2(1, 1) + }, + clearcoatNormalMap: { + value: null + }, + sheen: { + value: new Color(0x000000) + }, + transmission: { + value: 0 + }, + transmissionMap: { + value: null + } + }]), + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag + }; - return this; + function WebGLBackground(renderer, cubemaps, state, objects, premultipliedAlpha) { + var clearColor = new Color(0x000000); + var clearAlpha = 0; + var planeMesh; + var boxMesh; + var currentBackground = null; + var currentBackgroundVersion = 0; + var currentTonemapping = null; - }, + function render(renderList, scene, camera, forceClear) { + var background = scene.isScene === true ? scene.background : null; - toArray: function () { + if (background && background.isTexture) { + background = cubemaps.get(background); + } // Ignore background in AR + // TODO: Reconsider this. - var te = this.elements; - return [ - te[ 0 ], te[ 1 ], te[ 2 ], - te[ 3 ], te[ 4 ], te[ 5 ], - te[ 6 ], te[ 7 ], te[ 8 ] - ]; + var xr = renderer.xr; + var session = xr.getSession && xr.getSession(); - }, + if (session && session.environmentBlendMode === 'additive') { + background = null; + } - clone: function () { + if (background === null) { + setClear(clearColor, clearAlpha); + } else if (background && background.isColor) { + setClear(background, 1); + forceClear = true; + } - var te = this.elements; + if (renderer.autoClear || forceClear) { + renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil); + } - return new THREE.Matrix3( + if (background && (background.isCubeTexture || background.isWebGLCubeRenderTarget || background.mapping === CubeUVReflectionMapping)) { + if (boxMesh === undefined) { + boxMesh = new Mesh(new BoxBufferGeometry(1, 1, 1), new ShaderMaterial({ + name: 'BackgroundCubeMaterial', + uniforms: cloneUniforms(ShaderLib.cube.uniforms), + vertexShader: ShaderLib.cube.vertexShader, + fragmentShader: ShaderLib.cube.fragmentShader, + side: BackSide, + depthTest: false, + depthWrite: false, + fog: false + })); + boxMesh.geometry.deleteAttribute('normal'); + boxMesh.geometry.deleteAttribute('uv'); - te[0], te[3], te[6], - te[1], te[4], te[7], - te[2], te[5], te[8] + boxMesh.onBeforeRender = function (renderer, scene, camera) { + this.matrixWorld.copyPosition(camera.matrixWorld); + }; // enable code injection for non-built-in material - ); - } + Object.defineProperty(boxMesh.material, 'envMap', { + get: function get() { + return this.uniforms.envMap.value; + } + }); + objects.update(boxMesh); + } -}; + if (background.isWebGLCubeRenderTarget) { + // TODO Deprecate + background = background.texture; + } -/** - * @author mrdoob / http://mrdoob.com/ - * @author supereggbert / http://www.paulbrunt.co.uk/ - * @author philogb / http://blog.thejit.org/ - * @author jordi_ros / http://plattsoft.com - * @author D1plo1d / http://github.com/D1plo1d - * @author alteredq / http://alteredqualia.com/ - * @author mikael emtinger / http://gomo.se/ - * @author timknip / http://www.floorplanner.com/ - * @author bhouston / http://exocortex.com - * @author WestLangley / http://github.com/WestLangley - */ + boxMesh.material.uniforms.envMap.value = background; + boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture && background._needsFlipEnvMap ? -1 : 1; + + if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { + boxMesh.material.needsUpdate = true; + currentBackground = background; + currentBackgroundVersion = background.version; + currentTonemapping = renderer.toneMapping; + } // push to the pre-sorted opaque render list + + + renderList.unshift(boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null); + } else if (background && background.isTexture) { + if (planeMesh === undefined) { + planeMesh = new Mesh(new PlaneBufferGeometry(2, 2), new ShaderMaterial({ + name: 'BackgroundMaterial', + uniforms: cloneUniforms(ShaderLib.background.uniforms), + vertexShader: ShaderLib.background.vertexShader, + fragmentShader: ShaderLib.background.fragmentShader, + side: FrontSide, + depthTest: false, + depthWrite: false, + fog: false + })); + planeMesh.geometry.deleteAttribute('normal'); // enable code injection for non-built-in material + + Object.defineProperty(planeMesh.material, 'map', { + get: function get() { + return this.uniforms.t2D.value; + } + }); + objects.update(planeMesh); + } + planeMesh.material.uniforms.t2D.value = background; -THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { + if (background.matrixAutoUpdate === true) { + background.updateMatrix(); + } - this.elements = new Float32Array( 16 ); + planeMesh.material.uniforms.uvTransform.value.copy(background.matrix); - // TODO: if n11 is undefined, then just set to identity, otherwise copy all other values into matrix - // we should not support semi specification of Matrix4, it is just weird. + if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { + planeMesh.material.needsUpdate = true; + currentBackground = background; + currentBackgroundVersion = background.version; + currentTonemapping = renderer.toneMapping; + } // push to the pre-sorted opaque render list - var te = this.elements; - te[0] = ( n11 !== undefined ) ? n11 : 1; te[4] = n12 || 0; te[8] = n13 || 0; te[12] = n14 || 0; - te[1] = n21 || 0; te[5] = ( n22 !== undefined ) ? n22 : 1; te[9] = n23 || 0; te[13] = n24 || 0; - te[2] = n31 || 0; te[6] = n32 || 0; te[10] = ( n33 !== undefined ) ? n33 : 1; te[14] = n34 || 0; - te[3] = n41 || 0; te[7] = n42 || 0; te[11] = n43 || 0; te[15] = ( n44 !== undefined ) ? n44 : 1; + renderList.unshift(planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null); + } + } -}; + function setClear(color, alpha) { + state.buffers.color.setClear(color.r, color.g, color.b, alpha, premultipliedAlpha); + } -THREE.Matrix4.prototype = { + return { + getClearColor: function getClearColor() { + return clearColor; + }, + setClearColor: function setClearColor(color, alpha) { + clearColor.set(color); + clearAlpha = alpha !== undefined ? alpha : 1; + setClear(clearColor, clearAlpha); + }, + getClearAlpha: function getClearAlpha() { + return clearAlpha; + }, + setClearAlpha: function setClearAlpha(alpha) { + clearAlpha = alpha; + setClear(clearColor, clearAlpha); + }, + render: render + }; + } - constructor: THREE.Matrix4, + function WebGLBindingStates(gl, extensions, attributes, capabilities) { + var maxVertexAttributes = gl.getParameter(34921); + var extension = capabilities.isWebGL2 ? null : extensions.get('OES_vertex_array_object'); + var vaoAvailable = capabilities.isWebGL2 || extension !== null; + var bindingStates = {}; + var defaultState = createBindingState(null); + var currentState = defaultState; - set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { + function setup(object, material, program, geometry, index) { + var updateBuffers = false; - var te = this.elements; + if (vaoAvailable) { + var state = getBindingState(geometry, program, material); - 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; + if (currentState !== state) { + currentState = state; + bindVertexArrayObject(currentState.object); + } - return this; + updateBuffers = needsUpdate(geometry, index); + if (updateBuffers) saveCache(geometry, index); + } else { + var wireframe = material.wireframe === true; - }, + if (currentState.geometry !== geometry.id || currentState.program !== program.id || currentState.wireframe !== wireframe) { + currentState.geometry = geometry.id; + currentState.program = program.id; + currentState.wireframe = wireframe; + updateBuffers = true; + } + } - identity: function () { + if (object.isInstancedMesh === true) { + updateBuffers = true; + } - this.set( + if (index !== null) { + attributes.update(index, 34963); + } - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + if (updateBuffers) { + setupVertexAttributes(object, material, program, geometry); - ); + if (index !== null) { + gl.bindBuffer(34963, attributes.get(index).buffer); + } + } + } - return this; + function createVertexArrayObject() { + if (capabilities.isWebGL2) return gl.createVertexArray(); + return extension.createVertexArrayOES(); + } - }, + function bindVertexArrayObject(vao) { + if (capabilities.isWebGL2) return gl.bindVertexArray(vao); + return extension.bindVertexArrayOES(vao); + } - copy: function ( m ) { + function deleteVertexArrayObject(vao) { + if (capabilities.isWebGL2) return gl.deleteVertexArray(vao); + return extension.deleteVertexArrayOES(vao); + } - this.elements.set( m.elements ); + function getBindingState(geometry, program, material) { + var wireframe = material.wireframe === true; + var programMap = bindingStates[geometry.id]; - return this; + if (programMap === undefined) { + programMap = {}; + bindingStates[geometry.id] = programMap; + } - }, + var stateMap = programMap[program.id]; - extractPosition: function ( m ) { + if (stateMap === undefined) { + stateMap = {}; + programMap[program.id] = stateMap; + } - console.warn( 'DEPRECATED: Matrix4\'s .extractPosition() has been renamed to .copyPosition().' ); - return this.copyPosition( m ); + var state = stateMap[wireframe]; - }, + if (state === undefined) { + state = createBindingState(createVertexArrayObject()); + stateMap[wireframe] = state; + } - copyPosition: function ( m ) { + return state; + } - var te = this.elements; - var me = m.elements; + function createBindingState(vao) { + var newAttributes = []; + var enabledAttributes = []; + var attributeDivisors = []; - te[12] = me[12]; - te[13] = me[13]; - te[14] = me[14]; + for (var i = 0; i < maxVertexAttributes; i++) { + newAttributes[i] = 0; + enabledAttributes[i] = 0; + attributeDivisors[i] = 0; + } - return this; + return { + // for backward compatibility on non-VAO support browser + geometry: null, + program: null, + wireframe: false, + newAttributes: newAttributes, + enabledAttributes: enabledAttributes, + attributeDivisors: attributeDivisors, + object: vao, + attributes: {}, + index: null + }; + } - }, + function needsUpdate(geometry, index) { + var cachedAttributes = currentState.attributes; + var geometryAttributes = geometry.attributes; + if (Object.keys(cachedAttributes).length !== Object.keys(geometryAttributes).length) return true; - extractRotation: function () { + for (var key in geometryAttributes) { + var cachedAttribute = cachedAttributes[key]; + var geometryAttribute = geometryAttributes[key]; + if (cachedAttribute === undefined) return true; + if (cachedAttribute.attribute !== geometryAttribute) return true; + if (cachedAttribute.data !== geometryAttribute.data) return true; + } - var v1 = new THREE.Vector3(); + if (currentState.index !== index) return true; + return false; + } - return function ( m ) { + function saveCache(geometry, index) { + var cache = {}; + var attributes = geometry.attributes; - var te = this.elements; - var me = m.elements; + for (var key in attributes) { + var attribute = attributes[key]; + var data = {}; + data.attribute = attribute; - var scaleX = 1 / v1.set( me[0], me[1], me[2] ).length(); - var scaleY = 1 / v1.set( me[4], me[5], me[6] ).length(); - var scaleZ = 1 / v1.set( me[8], me[9], me[10] ).length(); + if (attribute.data) { + data.data = attribute.data; + } - te[0] = me[0] * scaleX; - te[1] = me[1] * scaleX; - te[2] = me[2] * scaleX; + cache[key] = data; + } - te[4] = me[4] * scaleY; - te[5] = me[5] * scaleY; - te[6] = me[6] * scaleY; + currentState.attributes = cache; + currentState.index = index; + } - te[8] = me[8] * scaleZ; - te[9] = me[9] * scaleZ; - te[10] = me[10] * scaleZ; + function initAttributes() { + var newAttributes = currentState.newAttributes; - return this; + for (var i = 0, il = newAttributes.length; i < il; i++) { + newAttributes[i] = 0; + } + } - }; + function enableAttribute(attribute) { + enableAttributeAndDivisor(attribute, 0); + } - }(), + function enableAttributeAndDivisor(attribute, meshPerAttribute) { + var newAttributes = currentState.newAttributes; + var enabledAttributes = currentState.enabledAttributes; + var attributeDivisors = currentState.attributeDivisors; + newAttributes[attribute] = 1; - makeRotationFromEuler: function ( euler ) { + if (enabledAttributes[attribute] === 0) { + gl.enableVertexAttribArray(attribute); + enabledAttributes[attribute] = 1; + } - if ( euler instanceof THREE.Euler === false ) { + if (attributeDivisors[attribute] !== meshPerAttribute) { + var _extension = capabilities.isWebGL2 ? gl : extensions.get('ANGLE_instanced_arrays'); - console.error( 'ERROR: Matrix\'s .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order. Please update your code.' ); + _extension[capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE'](attribute, meshPerAttribute); + attributeDivisors[attribute] = meshPerAttribute; + } } - var te = this.elements; + function disableUnusedAttributes() { + var newAttributes = currentState.newAttributes; + var enabledAttributes = currentState.enabledAttributes; - var x = euler.x, y = euler.y, z = euler.z; - var a = Math.cos( x ), b = Math.sin( x ); - var c = Math.cos( y ), d = Math.sin( y ); - var e = Math.cos( z ), f = Math.sin( z ); + for (var i = 0, il = enabledAttributes.length; i < il; i++) { + if (enabledAttributes[i] !== newAttributes[i]) { + gl.disableVertexAttribArray(i); + enabledAttributes[i] = 0; + } + } + } - if ( euler.order === 'XYZ' ) { + function vertexAttribPointer(index, size, type, normalized, stride, offset) { + if (capabilities.isWebGL2 === true && (type === 5124 || type === 5125)) { + gl.vertexAttribIPointer(index, size, type, stride, offset); + } else { + gl.vertexAttribPointer(index, size, type, normalized, stride, offset); + } + } - var ae = a * e, af = a * f, be = b * e, bf = b * f; + function setupVertexAttributes(object, material, program, geometry) { + if (capabilities.isWebGL2 === false && (object.isInstancedMesh || geometry.isInstancedBufferGeometry)) { + if (extensions.get('ANGLE_instanced_arrays') === null) return; + } - te[0] = c * e; - te[4] = - c * f; - te[8] = d; + initAttributes(); + var geometryAttributes = geometry.attributes; + var programAttributes = program.getAttributes(); + var materialDefaultAttributeValues = material.defaultAttributeValues; - te[1] = af + be * d; - te[5] = ae - bf * d; - te[9] = - b * c; + for (var name in programAttributes) { + var programAttribute = programAttributes[name]; - te[2] = bf - ae * d; - te[6] = be + af * d; - te[10] = a * c; + if (programAttribute >= 0) { + var geometryAttribute = geometryAttributes[name]; - } else if ( euler.order === 'YXZ' ) { + if (geometryAttribute !== undefined) { + var normalized = geometryAttribute.normalized; + var size = geometryAttribute.itemSize; + var attribute = attributes.get(geometryAttribute); // TODO Attribute may not be available on context restore - var ce = c * e, cf = c * f, de = d * e, df = d * f; + if (attribute === undefined) continue; + var buffer = attribute.buffer; + var type = attribute.type; + var bytesPerElement = attribute.bytesPerElement; - te[0] = ce + df * b; - te[4] = de * b - cf; - te[8] = a * d; + if (geometryAttribute.isInterleavedBufferAttribute) { + var data = geometryAttribute.data; + var stride = data.stride; + var offset = geometryAttribute.offset; - te[1] = a * f; - te[5] = a * e; - te[9] = - b; + if (data && data.isInstancedInterleavedBuffer) { + enableAttributeAndDivisor(programAttribute, data.meshPerAttribute); - te[2] = cf * b - de; - te[6] = df + ce * b; - te[10] = a * c; + if (geometry._maxInstanceCount === undefined) { + geometry._maxInstanceCount = data.meshPerAttribute * data.count; + } + } else { + enableAttribute(programAttribute); + } - } else if ( euler.order === 'ZXY' ) { + gl.bindBuffer(34962, buffer); + vertexAttribPointer(programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement); + } else { + if (geometryAttribute.isInstancedBufferAttribute) { + enableAttributeAndDivisor(programAttribute, geometryAttribute.meshPerAttribute); - var ce = c * e, cf = c * f, de = d * e, df = d * f; + if (geometry._maxInstanceCount === undefined) { + geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; + } + } else { + enableAttribute(programAttribute); + } - te[0] = ce - df * b; - te[4] = - a * f; - te[8] = de + cf * b; + gl.bindBuffer(34962, buffer); + vertexAttribPointer(programAttribute, size, type, normalized, 0, 0); + } + } else if (name === 'instanceMatrix') { + var _attribute = attributes.get(object.instanceMatrix); // TODO Attribute may not be available on context restore + + + if (_attribute === undefined) continue; + var _buffer = _attribute.buffer; + var _type = _attribute.type; + enableAttributeAndDivisor(programAttribute + 0, 1); + enableAttributeAndDivisor(programAttribute + 1, 1); + enableAttributeAndDivisor(programAttribute + 2, 1); + enableAttributeAndDivisor(programAttribute + 3, 1); + gl.bindBuffer(34962, _buffer); + gl.vertexAttribPointer(programAttribute + 0, 4, _type, false, 64, 0); + gl.vertexAttribPointer(programAttribute + 1, 4, _type, false, 64, 16); + gl.vertexAttribPointer(programAttribute + 2, 4, _type, false, 64, 32); + gl.vertexAttribPointer(programAttribute + 3, 4, _type, false, 64, 48); + } else if (name === 'instanceColor') { + var _attribute2 = attributes.get(object.instanceColor); // TODO Attribute may not be available on context restore + + + if (_attribute2 === undefined) continue; + var _buffer2 = _attribute2.buffer; + var _type2 = _attribute2.type; + enableAttributeAndDivisor(programAttribute, 1); + gl.bindBuffer(34962, _buffer2); + gl.vertexAttribPointer(programAttribute, 3, _type2, false, 12, 0); + } else if (materialDefaultAttributeValues !== undefined) { + var value = materialDefaultAttributeValues[name]; + + if (value !== undefined) { + switch (value.length) { + case 2: + gl.vertexAttrib2fv(programAttribute, value); + break; + + case 3: + gl.vertexAttrib3fv(programAttribute, value); + break; + + case 4: + gl.vertexAttrib4fv(programAttribute, value); + break; + + default: + gl.vertexAttrib1fv(programAttribute, value); + } + } + } + } + } - te[1] = cf + de * b; - te[5] = a * e; - te[9] = df - ce * b; + disableUnusedAttributes(); + } - te[2] = - a * d; - te[6] = b; - te[10] = a * c; + function dispose() { + reset(); - } else if ( euler.order === 'ZYX' ) { + for (var geometryId in bindingStates) { + var programMap = bindingStates[geometryId]; - var ae = a * e, af = a * f, be = b * e, bf = b * f; + for (var programId in programMap) { + var stateMap = programMap[programId]; - te[0] = c * e; - te[4] = be * d - af; - te[8] = ae * d + bf; + for (var wireframe in stateMap) { + deleteVertexArrayObject(stateMap[wireframe].object); + delete stateMap[wireframe]; + } - te[1] = c * f; - te[5] = bf * d + ae; - te[9] = af * d - be; + delete programMap[programId]; + } - te[2] = - d; - te[6] = b * c; - te[10] = a * c; + delete bindingStates[geometryId]; + } + } - } else if ( euler.order === 'YZX' ) { + function releaseStatesOfGeometry(geometry) { + if (bindingStates[geometry.id] === undefined) return; + var programMap = bindingStates[geometry.id]; - var ac = a * c, ad = a * d, bc = b * c, bd = b * d; + for (var programId in programMap) { + var stateMap = programMap[programId]; - te[0] = c * e; - te[4] = bd - ac * f; - te[8] = bc * f + ad; + for (var wireframe in stateMap) { + deleteVertexArrayObject(stateMap[wireframe].object); + delete stateMap[wireframe]; + } - te[1] = f; - te[5] = a * e; - te[9] = - b * e; + delete programMap[programId]; + } - te[2] = - d * e; - te[6] = ad * f + bc; - te[10] = ac - bd * f; + delete bindingStates[geometry.id]; + } - } else if ( euler.order === 'XZY' ) { + function releaseStatesOfProgram(program) { + for (var geometryId in bindingStates) { + var programMap = bindingStates[geometryId]; + if (programMap[program.id] === undefined) continue; + var stateMap = programMap[program.id]; - var ac = a * c, ad = a * d, bc = b * c, bd = b * d; + for (var wireframe in stateMap) { + deleteVertexArrayObject(stateMap[wireframe].object); + delete stateMap[wireframe]; + } - te[0] = c * e; - te[4] = - f; - te[8] = d * e; + delete programMap[program.id]; + } + } - te[1] = ac * f + bd; - te[5] = a * e; - te[9] = ad * f - bc; + function reset() { + resetDefaultState(); + if (currentState === defaultState) return; + currentState = defaultState; + bindVertexArrayObject(currentState.object); + } // for backward-compatilibity - te[2] = bc * f - ad; - te[6] = b * e; - te[10] = bd * f + ac; + function resetDefaultState() { + defaultState.geometry = null; + defaultState.program = null; + defaultState.wireframe = false; } - // last column - te[3] = 0; - te[7] = 0; - te[11] = 0; + return { + setup: setup, + reset: reset, + resetDefaultState: resetDefaultState, + dispose: dispose, + releaseStatesOfGeometry: releaseStatesOfGeometry, + releaseStatesOfProgram: releaseStatesOfProgram, + initAttributes: initAttributes, + enableAttribute: enableAttribute, + disableUnusedAttributes: disableUnusedAttributes + }; + } - // bottom row - te[12] = 0; - te[13] = 0; - te[14] = 0; - te[15] = 1; + function WebGLBufferRenderer(gl, extensions, info, capabilities) { + var isWebGL2 = capabilities.isWebGL2; + var mode; - return this; + function setMode(value) { + mode = value; + } - }, + function render(start, count) { + gl.drawArrays(mode, start, count); + info.update(count, mode, 1); + } - setRotationFromQuaternion: function ( q ) { + function renderInstances(start, count, primcount) { + if (primcount === 0) return; + var extension, methodName; - console.warn( 'DEPRECATED: Matrix4\'s .setRotationFromQuaternion() has been deprecated in favor of makeRotationFromQuaternion. Please update your code.' ); + if (isWebGL2) { + extension = gl; + methodName = 'drawArraysInstanced'; + } else { + extension = extensions.get('ANGLE_instanced_arrays'); + methodName = 'drawArraysInstancedANGLE'; - return this.makeRotationFromQuaternion( q ); + if (extension === null) { + console.error('THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.'); + return; + } + } - }, + extension[methodName](mode, start, count, primcount); + info.update(count, mode, primcount); + } // - makeRotationFromQuaternion: function ( q ) { - var te = this.elements; + this.setMode = setMode; + this.render = render; + this.renderInstances = renderInstances; + } - var x = q.x, y = q.y, z = q.z, w = q.w; - var x2 = x + x, y2 = y + y, z2 = z + z; - var xx = x * x2, xy = x * y2, xz = x * z2; - var yy = y * y2, yz = y * z2, zz = z * z2; - var wx = w * x2, wy = w * y2, wz = w * z2; + function WebGLCapabilities(gl, extensions, parameters) { + var maxAnisotropy; - te[0] = 1 - ( yy + zz ); - te[4] = xy - wz; - te[8] = xz + wy; + function getMaxAnisotropy() { + if (maxAnisotropy !== undefined) return maxAnisotropy; + var extension = extensions.get('EXT_texture_filter_anisotropic'); - te[1] = xy + wz; - te[5] = 1 - ( xx + zz ); - te[9] = yz - wx; + if (extension !== null) { + maxAnisotropy = gl.getParameter(extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT); + } else { + maxAnisotropy = 0; + } - te[2] = xz - wy; - te[6] = yz + wx; - te[10] = 1 - ( xx + yy ); + return maxAnisotropy; + } - // last column - te[3] = 0; - te[7] = 0; - te[11] = 0; + function getMaxPrecision(precision) { + if (precision === 'highp') { + if (gl.getShaderPrecisionFormat(35633, 36338).precision > 0 && gl.getShaderPrecisionFormat(35632, 36338).precision > 0) { + return 'highp'; + } - // bottom row - te[12] = 0; - te[13] = 0; - te[14] = 0; - te[15] = 1; + precision = 'mediump'; + } - return this; + if (precision === 'mediump') { + if (gl.getShaderPrecisionFormat(35633, 36337).precision > 0 && gl.getShaderPrecisionFormat(35632, 36337).precision > 0) { + return 'mediump'; + } + } - }, + return 'lowp'; + } + /* eslint-disable no-undef */ - lookAt: function() { - var x = new THREE.Vector3(); - var y = new THREE.Vector3(); - var z = new THREE.Vector3(); + var isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext || typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext; + /* eslint-enable no-undef */ - return function ( eye, target, up ) { + var precision = parameters.precision !== undefined ? parameters.precision : 'highp'; + var maxPrecision = getMaxPrecision(precision); - var te = this.elements; + if (maxPrecision !== precision) { + console.warn('THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.'); + precision = maxPrecision; + } - z.subVectors( eye, target ).normalize(); + var logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; + var maxTextures = gl.getParameter(34930); + var maxVertexTextures = gl.getParameter(35660); + var maxTextureSize = gl.getParameter(3379); + var maxCubemapSize = gl.getParameter(34076); + var maxAttributes = gl.getParameter(34921); + var maxVertexUniforms = gl.getParameter(36347); + var maxVaryings = gl.getParameter(36348); + var maxFragmentUniforms = gl.getParameter(36349); + var vertexTextures = maxVertexTextures > 0; + var floatFragmentTextures = isWebGL2 || !!extensions.get('OES_texture_float'); + var floatVertexTextures = vertexTextures && floatFragmentTextures; + var maxSamples = isWebGL2 ? gl.getParameter(36183) : 0; + return { + isWebGL2: isWebGL2, + getMaxAnisotropy: getMaxAnisotropy, + getMaxPrecision: getMaxPrecision, + precision: precision, + logarithmicDepthBuffer: logarithmicDepthBuffer, + maxTextures: maxTextures, + maxVertexTextures: maxVertexTextures, + maxTextureSize: maxTextureSize, + maxCubemapSize: maxCubemapSize, + maxAttributes: maxAttributes, + maxVertexUniforms: maxVertexUniforms, + maxVaryings: maxVaryings, + maxFragmentUniforms: maxFragmentUniforms, + vertexTextures: vertexTextures, + floatFragmentTextures: floatFragmentTextures, + floatVertexTextures: floatVertexTextures, + maxSamples: maxSamples + }; + } - if ( z.length() === 0 ) { + function WebGLClipping(properties) { + var scope = this; + var globalState = null, + numGlobalPlanes = 0, + localClippingEnabled = false, + renderingShadows = false; + var plane = new Plane(), + viewNormalMatrix = new Matrix3(), + uniform = { + value: null, + needsUpdate: false + }; + this.uniform = uniform; + this.numPlanes = 0; + this.numIntersection = 0; + + this.init = function (planes, enableLocalClipping, camera) { + var enabled = planes.length !== 0 || enableLocalClipping || // enable state of previous frame - the clipping code has to + // run another frame in order to reset the state: + numGlobalPlanes !== 0 || localClippingEnabled; + localClippingEnabled = enableLocalClipping; + globalState = projectPlanes(planes, camera, 0); + numGlobalPlanes = planes.length; + return enabled; + }; - z.z = 1; + this.beginShadows = function () { + renderingShadows = true; + projectPlanes(null); + }; - } + this.endShadows = function () { + renderingShadows = false; + resetGlobalState(); + }; - x.crossVectors( up, z ).normalize(); + this.setState = function (material, camera, useCache) { + var planes = material.clippingPlanes, + clipIntersection = material.clipIntersection, + clipShadows = material.clipShadows; + var materialProperties = properties.get(material); + + if (!localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && !clipShadows) { + // there's no local clipping + if (renderingShadows) { + // there's no global clipping + projectPlanes(null); + } else { + resetGlobalState(); + } + } else { + var nGlobal = renderingShadows ? 0 : numGlobalPlanes, + lGlobal = nGlobal * 4; + var dstArray = materialProperties.clippingState || null; + uniform.value = dstArray; // ensure unique state - if ( x.length() === 0 ) { + dstArray = projectPlanes(planes, camera, lGlobal, useCache); - z.x += 0.0001; - x.crossVectors( up, z ).normalize(); + for (var i = 0; i !== lGlobal; ++i) { + dstArray[i] = globalState[i]; + } + materialProperties.clippingState = dstArray; + this.numIntersection = clipIntersection ? this.numPlanes : 0; + this.numPlanes += nGlobal; } + }; - y.crossVectors( z, x ); + function resetGlobalState() { + if (uniform.value !== globalState) { + uniform.value = globalState; + uniform.needsUpdate = numGlobalPlanes > 0; + } + scope.numPlanes = numGlobalPlanes; + scope.numIntersection = 0; + } - 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; + function projectPlanes(planes, camera, dstOffset, skipTransform) { + var nPlanes = planes !== null ? planes.length : 0; + var dstArray = null; - return this; + if (nPlanes !== 0) { + dstArray = uniform.value; - }; + if (skipTransform !== true || dstArray === null) { + var flatSize = dstOffset + nPlanes * 4, + viewMatrix = camera.matrixWorldInverse; + viewNormalMatrix.getNormalMatrix(viewMatrix); - }(), + if (dstArray === null || dstArray.length < flatSize) { + dstArray = new Float32Array(flatSize); + } - multiply: function ( m, n ) { + for (var i = 0, i4 = dstOffset; i !== nPlanes; ++i, i4 += 4) { + plane.copy(planes[i]).applyMatrix4(viewMatrix, viewNormalMatrix); + plane.normal.toArray(dstArray, i4); + dstArray[i4 + 3] = plane.constant; + } + } - if ( n !== undefined ) { - - console.warn( 'DEPRECATED: Matrix4\'s .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); - return this.multiplyMatrices( m, n ); + uniform.value = dstArray; + uniform.needsUpdate = true; + } + scope.numPlanes = nPlanes; + scope.numIntersection = 0; + return dstArray; } + } - return this.multiplyMatrices( this, m ); - - }, - - multiplyMatrices: function ( a, b ) { + function WebGLCubeMaps(renderer) { + var cubemaps = new WeakMap(); - var ae = a.elements; - var be = b.elements; - var te = this.elements; + function mapTextureMapping(texture, mapping) { + if (mapping === EquirectangularReflectionMapping) { + texture.mapping = CubeReflectionMapping; + } else if (mapping === EquirectangularRefractionMapping) { + texture.mapping = CubeRefractionMapping; + } - var a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12]; - var a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13]; - var a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14]; - var a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15]; + return texture; + } - var b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12]; - var b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13]; - var b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14]; - var b41 = be[3], b42 = be[7], b43 = be[11], b44 = be[15]; + function get(texture) { + if (texture && texture.isTexture) { + var mapping = texture.mapping; - 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; + if (mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping) { + if (cubemaps.has(texture)) { + var cubemap = cubemaps.get(texture).texture; + return mapTextureMapping(cubemap, texture.mapping); + } else { + var image = texture.image; + + if (image && image.height > 0) { + var currentRenderList = renderer.getRenderList(); + var currentRenderTarget = renderer.getRenderTarget(); + var currentRenderState = renderer.getRenderState(); + var renderTarget = new WebGLCubeRenderTarget(image.height / 2); + renderTarget.fromEquirectangularTexture(renderer, texture); + cubemaps.set(texture, renderTarget); + renderer.setRenderTarget(currentRenderTarget); + renderer.setRenderList(currentRenderList); + renderer.setRenderState(currentRenderState); + texture.addEventListener('dispose', onTextureDispose); + return mapTextureMapping(renderTarget.texture, texture.mapping); + } else { + // image not yet ready. try the conversion next frame + return null; + } + } + } + } - 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; + return texture; + } - 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; + function onTextureDispose(event) { + var texture = event.target; + texture.removeEventListener('dispose', onTextureDispose); + var cubemap = cubemaps.get(texture); - 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; + if (cubemap !== undefined) { + cubemaps.delete(texture); + cubemap.dispose(); + } + } - return this; + function dispose() { + cubemaps = new WeakMap(); + } - }, + return { + get: get, + dispose: dispose + }; + } - multiplyToArray: function ( a, b, r ) { + function WebGLExtensions(gl) { + var extensions = {}; + return { + has: function has(name) { + if (extensions[name] !== undefined) { + return extensions[name] !== null; + } - var te = this.elements; + var extension; - this.multiplyMatrices( a, b ); + switch (name) { + case 'WEBGL_depth_texture': + extension = gl.getExtension('WEBGL_depth_texture') || gl.getExtension('MOZ_WEBGL_depth_texture') || gl.getExtension('WEBKIT_WEBGL_depth_texture'); + break; - r[ 0 ] = te[0]; r[ 1 ] = te[1]; r[ 2 ] = te[2]; r[ 3 ] = te[3]; - r[ 4 ] = te[4]; r[ 5 ] = te[5]; r[ 6 ] = te[6]; r[ 7 ] = te[7]; - r[ 8 ] = te[8]; r[ 9 ] = te[9]; r[ 10 ] = te[10]; r[ 11 ] = te[11]; - r[ 12 ] = te[12]; r[ 13 ] = te[13]; r[ 14 ] = te[14]; r[ 15 ] = te[15]; + case 'EXT_texture_filter_anisotropic': + extension = gl.getExtension('EXT_texture_filter_anisotropic') || gl.getExtension('MOZ_EXT_texture_filter_anisotropic') || gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic'); + break; - return this; + case 'WEBGL_compressed_texture_s3tc': + extension = gl.getExtension('WEBGL_compressed_texture_s3tc') || gl.getExtension('MOZ_WEBGL_compressed_texture_s3tc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc'); + break; - }, + case 'WEBGL_compressed_texture_pvrtc': + extension = gl.getExtension('WEBGL_compressed_texture_pvrtc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc'); + break; - multiplyScalar: function ( s ) { + default: + extension = gl.getExtension(name); + } - var te = this.elements; + extensions[name] = extension; + return extension !== null; + }, + get: function get(name) { + if (!this.has(name)) { + console.warn('THREE.WebGLRenderer: ' + name + ' extension not supported.'); + } - 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 extensions[name]; + } + }; + } - return this; + function WebGLGeometries(gl, attributes, info, bindingStates) { + var geometries = new WeakMap(); + var wireframeAttributes = new WeakMap(); - }, + function onGeometryDispose(event) { + var geometry = event.target; + var buffergeometry = geometries.get(geometry); - multiplyVector3: function ( vector ) { + if (buffergeometry.index !== null) { + attributes.remove(buffergeometry.index); + } - console.warn( 'DEPRECATED: Matrix4\'s .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' ); - return vector.applyProjection( this ); + for (var name in buffergeometry.attributes) { + attributes.remove(buffergeometry.attributes[name]); + } - }, + geometry.removeEventListener('dispose', onGeometryDispose); + geometries.delete(geometry); + var attribute = wireframeAttributes.get(buffergeometry); - multiplyVector4: function ( vector ) { + if (attribute) { + attributes.remove(attribute); + wireframeAttributes.delete(buffergeometry); + } - console.warn( 'DEPRECATED: Matrix4\'s .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); - return vector.applyMatrix4( this ); + bindingStates.releaseStatesOfGeometry(buffergeometry); - }, + if (geometry.isInstancedBufferGeometry === true) { + delete geometry._maxInstanceCount; + } // - multiplyVector3Array: function ( a ) { - console.warn( 'DEPRECATED: Matrix4\'s .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); - return this.applyToVector3Array( a ); + info.memory.geometries--; + } - }, + function get(object, geometry) { + var buffergeometry = geometries.get(geometry); + if (buffergeometry) return buffergeometry; + geometry.addEventListener('dispose', onGeometryDispose); - applyToVector3Array: function() { + if (geometry.isBufferGeometry) { + buffergeometry = geometry; + } else if (geometry.isGeometry) { + if (geometry._bufferGeometry === undefined) { + geometry._bufferGeometry = new BufferGeometry().setFromObject(object); + } - var v1 = new THREE.Vector3(); + buffergeometry = geometry._bufferGeometry; + } - return function ( array, offset, length ) { + geometries.set(geometry, buffergeometry); + info.memory.geometries++; + return buffergeometry; + } - if ( offset === undefined ) offset = 0; - if ( length === undefined ) length = array.length; + function update(geometry) { + var geometryAttributes = geometry.attributes; // Updating index buffer in VAO now. See WebGLBindingStates. - for ( var i = 0, j = offset, il; i < length; i += 3, j += 3 ) { + for (var name in geometryAttributes) { + attributes.update(geometryAttributes[name], 34962); + } // morph targets - v1.x = array[ j ]; - v1.y = array[ j + 1 ]; - v1.z = array[ j + 2 ]; - v1.applyMatrix4( this ); + var morphAttributes = geometry.morphAttributes; - array[ j ] = v1.x; - array[ j + 1 ] = v1.y; - array[ j + 2 ] = v1.z; + for (var _name in morphAttributes) { + var array = morphAttributes[_name]; + for (var i = 0, l = array.length; i < l; i++) { + attributes.update(array[i], 34962); + } } + } - return array; - - }; + function updateWireframeAttribute(geometry) { + var indices = []; + var geometryIndex = geometry.index; + var geometryPosition = geometry.attributes.position; + var version = 0; - }(), + if (geometryIndex !== null) { + var array = geometryIndex.array; + version = geometryIndex.version; - rotateAxis: function ( v ) { + for (var i = 0, l = array.length; i < l; i += 3) { + var a = array[i + 0]; + var b = array[i + 1]; + var c = array[i + 2]; + indices.push(a, b, b, c, c, a); + } + } else { + var _array = geometryPosition.array; + version = geometryPosition.version; - console.warn( 'DEPRECATED: Matrix4\'s .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); + for (var _i = 0, _l = _array.length / 3 - 1; _i < _l; _i += 3) { + var _a = _i + 0; - v.transformDirection( this ); + var _b = _i + 1; - }, + var _c = _i + 2; - crossVector: function ( vector ) { + indices.push(_a, _b, _b, _c, _c, _a); + } + } - console.warn( 'DEPRECATED: Matrix4\'s .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); - return vector.applyMatrix4( this ); + var attribute = new (arrayMax(indices) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); + attribute.version = version; // Updating index buffer in VAO now. See WebGLBindingStates + // - }, + var previousAttribute = wireframeAttributes.get(geometry); + if (previousAttribute) attributes.remove(previousAttribute); // - determinant: function () { + wireframeAttributes.set(geometry, attribute); + } - var te = this.elements; + function getWireframeAttribute(geometry) { + var currentAttribute = wireframeAttributes.get(geometry); - var n11 = te[0], n12 = te[4], n13 = te[8], n14 = te[12]; - var n21 = te[1], n22 = te[5], n23 = te[9], n24 = te[13]; - var n31 = te[2], n32 = te[6], n33 = te[10], n34 = te[14]; - var n41 = te[3], n42 = te[7], n43 = te[11], n44 = te[15]; + if (currentAttribute) { + var geometryIndex = geometry.index; - //TODO: make this more efficient - //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) + if (geometryIndex !== null) { + // if the attribute is obsolete, create a new one + if (currentAttribute.version < geometryIndex.version) { + updateWireframeAttribute(geometry); + } + } + } else { + updateWireframeAttribute(geometry); + } - 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 - ) + return wireframeAttributes.get(geometry); + } - ); + return { + get: get, + update: update, + getWireframeAttribute: getWireframeAttribute + }; + } - }, + function WebGLIndexedBufferRenderer(gl, extensions, info, capabilities) { + var isWebGL2 = capabilities.isWebGL2; + var mode; - transpose: function () { + function setMode(value) { + mode = value; + } - var te = this.elements; - var tmp; + var type, bytesPerElement; - 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; + function setIndex(value) { + type = value.type; + bytesPerElement = value.bytesPerElement; + } - 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; + function render(start, count) { + gl.drawElements(mode, count, type, start * bytesPerElement); + info.update(count, mode, 1); + } - return this; + function renderInstances(start, count, primcount) { + if (primcount === 0) return; + var extension, methodName; - }, + if (isWebGL2) { + extension = gl; + methodName = 'drawElementsInstanced'; + } else { + extension = extensions.get('ANGLE_instanced_arrays'); + methodName = 'drawElementsInstancedANGLE'; - flattenToArrayOffset: function( array, offset ) { + if (extension === null) { + console.error('THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.'); + return; + } + } - var te = this.elements; + extension[methodName](mode, count, type, start * bytesPerElement, primcount); + info.update(count, mode, primcount); + } // - 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]; + this.setMode = setMode; + this.setIndex = setIndex; + this.render = render; + this.renderInstances = renderInstances; + } - array[ offset + 8 ] = te[8]; - array[ offset + 9 ] = te[9]; - array[ offset + 10 ] = te[10]; - array[ offset + 11 ] = te[11]; + function WebGLInfo(gl) { + var memory = { + geometries: 0, + textures: 0 + }; + var render = { + frame: 0, + calls: 0, + triangles: 0, + points: 0, + lines: 0 + }; - array[ offset + 12 ] = te[12]; - array[ offset + 13 ] = te[13]; - array[ offset + 14 ] = te[14]; - array[ offset + 15 ] = te[15]; + function update(count, mode, instanceCount) { + render.calls++; - return array; + switch (mode) { + case 4: + render.triangles += instanceCount * (count / 3); + break; - }, + case 1: + render.lines += instanceCount * (count / 2); + break; - getPosition: function() { + case 3: + render.lines += instanceCount * (count - 1); + break; - var v1 = new THREE.Vector3(); + case 2: + render.lines += instanceCount * count; + break; - return function () { + case 0: + render.points += instanceCount * count; + break; - console.warn( 'DEPRECATED: Matrix4\'s .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); + default: + console.error('THREE.WebGLInfo: Unknown draw mode:', mode); + break; + } + } - var te = this.elements; - return v1.set( te[12], te[13], te[14] ); + function reset() { + render.frame++; + render.calls = 0; + render.triangles = 0; + render.points = 0; + render.lines = 0; + } + return { + memory: memory, + render: render, + programs: null, + autoReset: true, + reset: reset, + update: update }; + } - }(), - - setPosition: function ( v ) { - - var te = this.elements; - - te[12] = v.x; - te[13] = v.y; - te[14] = v.z; - - return this; - - }, + function numericalSort(a, b) { + return a[0] - b[0]; + } - getInverse: function ( m, throwOnInvertible ) { + function absNumericalSort(a, b) { + return Math.abs(b[1]) - Math.abs(a[1]); + } - // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm - var te = this.elements; - var me = m.elements; + function WebGLMorphtargets(gl) { + var influencesList = {}; + var morphInfluences = new Float32Array(8); + var workInfluences = []; - var n11 = me[0], n12 = me[4], n13 = me[8], n14 = me[12]; - var n21 = me[1], n22 = me[5], n23 = me[9], n24 = me[13]; - var n31 = me[2], n32 = me[6], n33 = me[10], n34 = me[14]; - var n41 = me[3], n42 = me[7], n43 = me[11], n44 = me[15]; + for (var i = 0; i < 8; i++) { + workInfluences[i] = [i, 0]; + } - te[0] = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44; - te[4] = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44; - te[8] = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44; - te[12] = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34; - te[1] = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44; - te[5] = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44; - te[9] = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44; - te[13] = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34; - te[2] = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44; - te[6] = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44; - te[10] = n12*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44; - te[14] = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34; - te[3] = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43; - te[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43; - te[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43; - te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33; + function update(object, geometry, material, program) { + var objectInfluences = object.morphTargetInfluences; // When object doesn't have morph target influences defined, we treat it as a 0-length array + // This is important to make sure we set up morphTargetBaseInfluence / morphTargetInfluences - var det = n11 * te[ 0 ] + n21 * te[ 4 ] + n31 * te[ 8 ] + n41 * te[ 12 ]; + var length = objectInfluences === undefined ? 0 : objectInfluences.length; + var influences = influencesList[geometry.id]; - if ( det == 0 ) { + if (influences === undefined) { + // initialise list + influences = []; - var msg = "Matrix4.getInverse(): can't invert matrix, determinant is 0"; + for (var _i = 0; _i < length; _i++) { + influences[_i] = [_i, 0]; + } - if ( throwOnInvertible || false ) { + influencesList[geometry.id] = influences; + } // Collect influences - throw new Error( msg ); - } else { + for (var _i2 = 0; _i2 < length; _i2++) { + var influence = influences[_i2]; + influence[0] = _i2; + influence[1] = objectInfluences[_i2]; + } - console.warn( msg ); + influences.sort(absNumericalSort); + for (var _i3 = 0; _i3 < 8; _i3++) { + if (_i3 < length && influences[_i3][1]) { + workInfluences[_i3][0] = influences[_i3][0]; + workInfluences[_i3][1] = influences[_i3][1]; + } else { + workInfluences[_i3][0] = Number.MAX_SAFE_INTEGER; + workInfluences[_i3][1] = 0; + } } - this.identity(); - - return this; - } + workInfluences.sort(numericalSort); + var morphTargets = material.morphTargets && geometry.morphAttributes.position; + var morphNormals = material.morphNormals && geometry.morphAttributes.normal; + var morphInfluencesSum = 0; - this.multiplyScalar( 1 / det ); + for (var _i4 = 0; _i4 < 8; _i4++) { + var _influence = workInfluences[_i4]; + var index = _influence[0]; + var value = _influence[1]; - return this; + if (index !== Number.MAX_SAFE_INTEGER && value) { + if (morphTargets && geometry.getAttribute('morphTarget' + _i4) !== morphTargets[index]) { + geometry.setAttribute('morphTarget' + _i4, morphTargets[index]); + } - }, + if (morphNormals && geometry.getAttribute('morphNormal' + _i4) !== morphNormals[index]) { + geometry.setAttribute('morphNormal' + _i4, morphNormals[index]); + } - translate: function ( v ) { + morphInfluences[_i4] = value; + morphInfluencesSum += value; + } else { + if (morphTargets && geometry.getAttribute('morphTarget' + _i4) !== undefined) { + geometry.deleteAttribute('morphTarget' + _i4); + } - console.warn( 'DEPRECATED: Matrix4\'s .translate() has been removed.'); + if (morphNormals && geometry.getAttribute('morphNormal' + _i4) !== undefined) { + geometry.deleteAttribute('morphNormal' + _i4); + } - }, + morphInfluences[_i4] = 0; + } + } // GLSL shader uses formula baseinfluence * base + sum(target * influence) + // This allows us to switch between absolute morphs and relative morphs without changing shader code + // When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence) - rotateX: function ( angle ) { - console.warn( 'DEPRECATED: Matrix4\'s .rotateX() has been removed.'); + var morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; + program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence); + program.getUniforms().setValue(gl, 'morphTargetInfluences', morphInfluences); + } - }, + return { + update: update + }; + } - rotateY: function ( angle ) { + function WebGLObjects(gl, geometries, attributes, info) { + var updateMap = new WeakMap(); - console.warn( 'DEPRECATED: Matrix4\'s .rotateY() has been removed.'); + function update(object) { + var frame = info.render.frame; + var geometry = object.geometry; + var buffergeometry = geometries.get(object, geometry); // Update once per frame - }, + if (updateMap.get(buffergeometry) !== frame) { + if (geometry.isGeometry) { + buffergeometry.updateFromObject(object); + } - rotateZ: function ( angle ) { + geometries.update(buffergeometry); + updateMap.set(buffergeometry, frame); + } - console.warn( 'DEPRECATED: Matrix4\'s .rotateZ() has been removed.'); + if (object.isInstancedMesh) { + attributes.update(object.instanceMatrix, 34962); - }, + if (object.instanceColor !== null) { + attributes.update(object.instanceColor, 34962); + } + } - rotateByAxis: function ( axis, angle ) { + return buffergeometry; + } - console.warn( 'DEPRECATED: Matrix4\'s .rotateByAxis() has been removed.'); + function dispose() { + updateMap = new WeakMap(); + } - }, + return { + update: update, + dispose: dispose + }; + } - scale: function ( v ) { + function DataTexture2DArray(data, width, height, depth) { + Texture.call(this, null); + this.image = { + data: data || null, + width: width || 1, + height: height || 1, + depth: depth || 1 + }; + this.magFilter = NearestFilter; + this.minFilter = NearestFilter; + this.wrapR = ClampToEdgeWrapping; + this.generateMipmaps = false; + this.flipY = false; + this.needsUpdate = true; + } - var te = this.elements; - var x = v.x, y = v.y, z = v.z; + DataTexture2DArray.prototype = Object.create(Texture.prototype); + DataTexture2DArray.prototype.constructor = DataTexture2DArray; + DataTexture2DArray.prototype.isDataTexture2DArray = true; - 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; + function DataTexture3D(data, width, height, depth) { + // We're going to add .setXXX() methods for setting properties later. + // Users can still set in DataTexture3D directly. + // + // const texture = new THREE.DataTexture3D( data, width, height, depth ); + // texture.anisotropy = 16; + // + // See #14839 + Texture.call(this, null); + this.image = { + data: data || null, + width: width || 1, + height: height || 1, + depth: depth || 1 + }; + this.magFilter = NearestFilter; + this.minFilter = NearestFilter; + this.wrapR = ClampToEdgeWrapping; + this.generateMipmaps = false; + this.flipY = false; + this.needsUpdate = true; + } + + DataTexture3D.prototype = Object.create(Texture.prototype); + DataTexture3D.prototype.constructor = DataTexture3D; + DataTexture3D.prototype.isDataTexture3D = true; + + /** + * Uniforms of a program. + * Those form a tree structure with a special top-level container for the root, + * which you get by calling 'new WebGLUniforms( gl, program )'. + * + * + * Properties of inner nodes including the top-level container: + * + * .seq - array of nested uniforms + * .map - nested uniforms by name + * + * + * Methods of all nodes except the top-level container: + * + * .setValue( gl, value, [textures] ) + * + * uploads a uniform value(s) + * the 'textures' parameter is needed for sampler uniforms + * + * + * Static methods of the top-level container (textures factorizations): + * + * .upload( gl, seq, values, textures ) + * + * sets uniforms in 'seq' to 'values[id].value' + * + * .seqWithValue( seq, values ) : filteredSeq + * + * filters 'seq' entries with corresponding entry in values + * + * + * Methods of the top-level container (textures factorizations): + * + * .setValue( gl, name, value, textures ) + * + * sets uniform with name 'name' to 'value' + * + * .setOptional( gl, obj, prop ) + * + * like .set for an optional property of the object + * + */ + var emptyTexture = new Texture(); + var emptyTexture2dArray = new DataTexture2DArray(); + var emptyTexture3d = new DataTexture3D(); + var emptyCubeTexture = new CubeTexture(); // --- Utilities --- + // Array Caches (provide typed arrays for temporary by size) - return this; + var arrayCacheF32 = []; + var arrayCacheI32 = []; // Float32Array caches used for uploading Matrix uniforms - }, + var mat4array = new Float32Array(16); + var mat3array = new Float32Array(9); + var mat2array = new Float32Array(4); // Flattening for arrays of vectors and matrices - getMaxScaleOnAxis: function () { + function flatten(array, nBlocks, blockSize) { + var firstElem = array[0]; + if (firstElem <= 0 || firstElem > 0) return array; // unoptimized: ! isNaN( firstElem ) + // see http://jacksondunstan.com/articles/983 - var te = this.elements; + var n = nBlocks * blockSize; + var r = arrayCacheF32[n]; - var scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2]; - var scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6]; - var scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10]; + if (r === undefined) { + r = new Float32Array(n); + arrayCacheF32[n] = r; + } - return Math.sqrt( Math.max( scaleXSq, Math.max( scaleYSq, scaleZSq ) ) ); + if (nBlocks !== 0) { + firstElem.toArray(r, 0); - }, + for (var i = 1, offset = 0; i !== nBlocks; ++i) { + offset += blockSize; + array[i].toArray(r, offset); + } + } - makeTranslation: function ( x, y, z ) { + return r; + } - this.set( + function arraysEqual(a, b) { + if (a.length !== b.length) return false; - 1, 0, 0, x, - 0, 1, 0, y, - 0, 0, 1, z, - 0, 0, 0, 1 + for (var i = 0, l = a.length; i < l; i++) { + if (a[i] !== b[i]) return false; + } - ); + return true; + } - return this; + function copyArray(a, b) { + for (var i = 0, l = b.length; i < l; i++) { + a[i] = b[i]; + } + } // Texture unit allocation - }, - makeRotationX: function ( theta ) { + function allocTexUnits(textures, n) { + var r = arrayCacheI32[n]; - var c = Math.cos( theta ), s = Math.sin( theta ); + if (r === undefined) { + r = new Int32Array(n); + arrayCacheI32[n] = r; + } - this.set( + for (var i = 0; i !== n; ++i) { + r[i] = textures.allocateTextureUnit(); + } - 1, 0, 0, 0, - 0, c, -s, 0, - 0, s, c, 0, - 0, 0, 0, 1 + return r; + } // --- Setters --- + // Note: Defining these methods externally, because they come in a bunch + // and this way their names minify. + // Single scalar - ); - return this; + function setValueV1f(gl, v) { + var cache = this.cache; + if (cache[0] === v) return; + gl.uniform1f(this.addr, v); + cache[0] = v; + } // Single float vector (from flat array or THREE.VectorN) - }, - makeRotationY: function ( theta ) { + function setValueV2f(gl, v) { + var cache = this.cache; - var c = Math.cos( theta ), s = Math.sin( theta ); + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y) { + gl.uniform2f(this.addr, v.x, v.y); + cache[0] = v.x; + cache[1] = v.y; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform2fv(this.addr, v); + copyArray(cache, v); + } + } - this.set( + function setValueV3f(gl, v) { + var cache = this.cache; - c, 0, s, 0, - 0, 1, 0, 0, - -s, 0, c, 0, - 0, 0, 0, 1 + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) { + gl.uniform3f(this.addr, v.x, v.y, v.z); + cache[0] = v.x; + cache[1] = v.y; + cache[2] = v.z; + } + } else if (v.r !== undefined) { + if (cache[0] !== v.r || cache[1] !== v.g || cache[2] !== v.b) { + gl.uniform3f(this.addr, v.r, v.g, v.b); + cache[0] = v.r; + cache[1] = v.g; + cache[2] = v.b; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform3fv(this.addr, v); + copyArray(cache, v); + } + } - ); + function setValueV4f(gl, v) { + var cache = this.cache; - return this; + if (v.x !== undefined) { + if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) { + gl.uniform4f(this.addr, v.x, v.y, v.z, v.w); + cache[0] = v.x; + cache[1] = v.y; + cache[2] = v.z; + cache[3] = v.w; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform4fv(this.addr, v); + copyArray(cache, v); + } + } // Single matrix (from flat array or MatrixN) - }, - makeRotationZ: function ( theta ) { + function setValueM2(gl, v) { + var cache = this.cache; + var elements = v.elements; - var c = Math.cos( theta ), s = Math.sin( theta ); + if (elements === undefined) { + if (arraysEqual(cache, v)) return; + gl.uniformMatrix2fv(this.addr, false, v); + copyArray(cache, v); + } else { + if (arraysEqual(cache, elements)) return; + mat2array.set(elements); + gl.uniformMatrix2fv(this.addr, false, mat2array); + copyArray(cache, elements); + } + } - this.set( + function setValueM3(gl, v) { + var cache = this.cache; + var elements = v.elements; - c, -s, 0, 0, - s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + if (elements === undefined) { + if (arraysEqual(cache, v)) return; + gl.uniformMatrix3fv(this.addr, false, v); + copyArray(cache, v); + } else { + if (arraysEqual(cache, elements)) return; + mat3array.set(elements); + gl.uniformMatrix3fv(this.addr, false, mat3array); + copyArray(cache, elements); + } + } - ); + function setValueM4(gl, v) { + var cache = this.cache; + var elements = v.elements; - return this; + if (elements === undefined) { + if (arraysEqual(cache, v)) return; + gl.uniformMatrix4fv(this.addr, false, v); + copyArray(cache, v); + } else { + if (arraysEqual(cache, elements)) return; + mat4array.set(elements); + gl.uniformMatrix4fv(this.addr, false, mat4array); + copyArray(cache, elements); + } + } // Single texture (2D / Cube) - }, - makeRotationAxis: function ( axis, angle ) { + function setValueT1(gl, v, textures) { + var cache = this.cache; + var unit = textures.allocateTextureUnit(); - // Based on http://www.gamedev.net/reference/articles/article1199.asp + if (cache[0] !== unit) { + gl.uniform1i(this.addr, unit); + cache[0] = unit; + } - var c = Math.cos( angle ); - var s = Math.sin( angle ); - var t = 1 - c; - var x = axis.x, y = axis.y, z = axis.z; - var tx = t * x, ty = t * y; + textures.safeSetTexture2D(v || emptyTexture, unit); + } - this.set( + function setValueT2DArray1(gl, v, textures) { + var cache = this.cache; + var unit = textures.allocateTextureUnit(); - 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 + if (cache[0] !== unit) { + gl.uniform1i(this.addr, unit); + cache[0] = unit; + } - ); + textures.setTexture2DArray(v || emptyTexture2dArray, unit); + } - return this; + function setValueT3D1(gl, v, textures) { + var cache = this.cache; + var unit = textures.allocateTextureUnit(); - }, + if (cache[0] !== unit) { + gl.uniform1i(this.addr, unit); + cache[0] = unit; + } - makeScale: function ( x, y, z ) { + textures.setTexture3D(v || emptyTexture3d, unit); + } - this.set( + function setValueT6(gl, v, textures) { + var cache = this.cache; + var unit = textures.allocateTextureUnit(); - x, 0, 0, 0, - 0, y, 0, 0, - 0, 0, z, 0, - 0, 0, 0, 1 + if (cache[0] !== unit) { + gl.uniform1i(this.addr, unit); + cache[0] = unit; + } - ); + textures.safeSetTextureCube(v || emptyCubeTexture, unit); + } // Integer / Boolean vectors or arrays thereof (always flat arrays) - return this; - }, + function setValueV1i(gl, v) { + var cache = this.cache; + if (cache[0] === v) return; + gl.uniform1i(this.addr, v); + cache[0] = v; + } - compose: function ( position, quaternion, scale ) { + function setValueV2i(gl, v) { + var cache = this.cache; + if (arraysEqual(cache, v)) return; + gl.uniform2iv(this.addr, v); + copyArray(cache, v); + } - this.makeRotationFromQuaternion( quaternion ); - this.scale( scale ); - this.setPosition( position ); + function setValueV3i(gl, v) { + var cache = this.cache; + if (arraysEqual(cache, v)) return; + gl.uniform3iv(this.addr, v); + copyArray(cache, v); + } - return this; + function setValueV4i(gl, v) { + var cache = this.cache; + if (arraysEqual(cache, v)) return; + gl.uniform4iv(this.addr, v); + copyArray(cache, v); + } // uint - }, - decompose: function () { + function setValueV1ui(gl, v) { + var cache = this.cache; + if (cache[0] === v) return; + gl.uniform1ui(this.addr, v); + cache[0] = v; + } // Helper to pick the right setter for the singular case - var vector = new THREE.Vector3(); - var matrix = new THREE.Matrix4(); - return function ( position, quaternion, scale ) { + function getSingularSetter(type) { + switch (type) { + case 0x1406: + return setValueV1f; + // FLOAT - var te = this.elements; + case 0x8b50: + return setValueV2f; + // _VEC2 - var sx = vector.set( te[0], te[1], te[2] ).length(); - var sy = vector.set( te[4], te[5], te[6] ).length(); - var sz = vector.set( te[8], te[9], te[10] ).length(); + case 0x8b51: + return setValueV3f; + // _VEC3 - // if determine is negative, we need to invert one scale - var det = this.determinant(); - if( det < 0 ) { - sx = -sx; - } + case 0x8b52: + return setValueV4f; + // _VEC4 - position.x = te[12]; - position.y = te[13]; - position.z = te[14]; + case 0x8b5a: + return setValueM2; + // _MAT2 - // scale the rotation part + case 0x8b5b: + return setValueM3; + // _MAT3 - matrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy() + case 0x8b5c: + return setValueM4; + // _MAT4 - var invSX = 1 / sx; - var invSY = 1 / sy; - var invSZ = 1 / sz; + case 0x1404: + case 0x8b56: + return setValueV1i; + // INT, BOOL - matrix.elements[0] *= invSX; - matrix.elements[1] *= invSX; - matrix.elements[2] *= invSX; + case 0x8b53: + case 0x8b57: + return setValueV2i; + // _VEC2 - matrix.elements[4] *= invSY; - matrix.elements[5] *= invSY; - matrix.elements[6] *= invSY; + case 0x8b54: + case 0x8b58: + return setValueV3i; + // _VEC3 - matrix.elements[8] *= invSZ; - matrix.elements[9] *= invSZ; - matrix.elements[10] *= invSZ; + case 0x8b55: + case 0x8b59: + return setValueV4i; + // _VEC4 - quaternion.setFromRotationMatrix( matrix ); + case 0x1405: + return setValueV1ui; + // UINT - scale.x = sx; - scale.y = sy; - scale.z = sz; + case 0x8b5e: // SAMPLER_2D - return this; + case 0x8d66: // SAMPLER_EXTERNAL_OES - }; + case 0x8dca: // INT_SAMPLER_2D - }(), + case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D - makeFrustum: function ( left, right, bottom, top, near, far ) { + case 0x8b62: + // SAMPLER_2D_SHADOW + return setValueT1; - var te = this.elements; - var x = 2 * near / ( right - left ); - var y = 2 * near / ( top - bottom ); + case 0x8b5f: // SAMPLER_3D - var a = ( right + left ) / ( right - left ); - var b = ( top + bottom ) / ( top - bottom ); - var c = - ( far + near ) / ( far - near ); - var d = - 2 * far * near / ( far - near ); + case 0x8dcb: // INT_SAMPLER_3D - 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; + case 0x8dd3: + // UNSIGNED_INT_SAMPLER_3D + return setValueT3D1; - return this; + case 0x8b60: // SAMPLER_CUBE - }, + case 0x8dcc: // INT_SAMPLER_CUBE - makePerspective: function ( fov, aspect, near, far ) { + case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE - var ymax = near * Math.tan( THREE.Math.degToRad( fov * 0.5 ) ); - var ymin = - ymax; - var xmin = ymin * aspect; - var xmax = ymax * aspect; + case 0x8dc5: + // SAMPLER_CUBE_SHADOW + return setValueT6; - return this.makeFrustum( xmin, xmax, ymin, ymax, near, far ); + case 0x8dc1: // SAMPLER_2D_ARRAY - }, + case 0x8dcf: // INT_SAMPLER_2D_ARRAY - makeOrthographic: function ( left, right, top, bottom, near, far ) { + case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY - var te = this.elements; - var w = right - left; - var h = top - bottom; - var p = far - near; + case 0x8dc4: + // SAMPLER_2D_ARRAY_SHADOW + return setValueT2DArray1; + } + } // Array of scalars - var x = ( right + left ) / w; - var y = ( top + bottom ) / h; - var 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; + function setValueV1fArray(gl, v) { + gl.uniform1fv(this.addr, v); + } // Integer / Boolean vectors or arrays thereof (always flat arrays) - return this; - }, + function setValueV1iArray(gl, v) { + gl.uniform1iv(this.addr, v); + } - fromArray: function ( array ) { + function setValueV2iArray(gl, v) { + gl.uniform2iv(this.addr, v); + } - this.elements.set( array ); + function setValueV3iArray(gl, v) { + gl.uniform3iv(this.addr, v); + } - return this; + function setValueV4iArray(gl, v) { + gl.uniform4iv(this.addr, v); + } // Array of vectors (flat or from THREE classes) - }, - toArray: function () { + function setValueV2fArray(gl, v) { + var data = flatten(v, this.size, 2); + gl.uniform2fv(this.addr, data); + } - var te = this.elements; + function setValueV3fArray(gl, v) { + var data = flatten(v, this.size, 3); + gl.uniform3fv(this.addr, data); + } - return [ - te[ 0 ], te[ 1 ], te[ 2 ], te[ 3 ], - te[ 4 ], te[ 5 ], te[ 6 ], te[ 7 ], - te[ 8 ], te[ 9 ], te[ 10 ], te[ 11 ], - te[ 12 ], te[ 13 ], te[ 14 ], te[ 15 ] - ]; + function setValueV4fArray(gl, v) { + var data = flatten(v, this.size, 4); + gl.uniform4fv(this.addr, data); + } // Array of matrices (flat or from THREE clases) - }, - clone: function () { + function setValueM2Array(gl, v) { + var data = flatten(v, this.size, 4); + gl.uniformMatrix2fv(this.addr, false, data); + } - var te = this.elements; + function setValueM3Array(gl, v) { + var data = flatten(v, this.size, 9); + gl.uniformMatrix3fv(this.addr, false, data); + } - return new THREE.Matrix4( + function setValueM4Array(gl, v) { + var data = flatten(v, this.size, 16); + gl.uniformMatrix4fv(this.addr, false, data); + } // Array of textures (2D / Cube) - te[0], te[4], te[8], te[12], - te[1], te[5], te[9], te[13], - te[2], te[6], te[10], te[14], - te[3], te[7], te[11], te[15] - ); + function setValueT1Array(gl, v, textures) { + var n = v.length; + var units = allocTexUnits(textures, n); + gl.uniform1iv(this.addr, units); + for (var i = 0; i !== n; ++i) { + textures.safeSetTexture2D(v[i] || emptyTexture, units[i]); + } } -}; + function setValueT6Array(gl, v, textures) { + var n = v.length; + var units = allocTexUnits(textures, n); + gl.uniform1iv(this.addr, units); -/** - * @author bhouston / http://exocortex.com - */ + for (var i = 0; i !== n; ++i) { + textures.safeSetTextureCube(v[i] || emptyCubeTexture, units[i]); + } + } // Helper to pick the right setter for a pure (bottom-level) array -THREE.Ray = function ( origin, direction ) { - this.origin = ( origin !== undefined ) ? origin : new THREE.Vector3(); - this.direction = ( direction !== undefined ) ? direction : new THREE.Vector3(); + function getPureArraySetter(type) { + switch (type) { + case 0x1406: + return setValueV1fArray; + // FLOAT -}; + case 0x8b50: + return setValueV2fArray; + // _VEC2 -THREE.Ray.prototype = { + case 0x8b51: + return setValueV3fArray; + // _VEC3 - constructor: THREE.Ray, + case 0x8b52: + return setValueV4fArray; + // _VEC4 - set: function ( origin, direction ) { + case 0x8b5a: + return setValueM2Array; + // _MAT2 - this.origin.copy( origin ); - this.direction.copy( direction ); + case 0x8b5b: + return setValueM3Array; + // _MAT3 - return this; + case 0x8b5c: + return setValueM4Array; + // _MAT4 - }, + case 0x1404: + case 0x8b56: + return setValueV1iArray; + // INT, BOOL - copy: function ( ray ) { + case 0x8b53: + case 0x8b57: + return setValueV2iArray; + // _VEC2 - this.origin.copy( ray.origin ); - this.direction.copy( ray.direction ); + case 0x8b54: + case 0x8b58: + return setValueV3iArray; + // _VEC3 - return this; + case 0x8b55: + case 0x8b59: + return setValueV4iArray; + // _VEC4 - }, + case 0x8b5e: // SAMPLER_2D - at: function ( t, optionalTarget ) { + case 0x8d66: // SAMPLER_EXTERNAL_OES - var result = optionalTarget || new THREE.Vector3(); + case 0x8dca: // INT_SAMPLER_2D - return result.copy( this.direction ).multiplyScalar( t ).add( this.origin ); + case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D - }, + case 0x8b62: + // SAMPLER_2D_SHADOW + return setValueT1Array; - recast: function () { + case 0x8b60: // SAMPLER_CUBE - var v1 = new THREE.Vector3(); + case 0x8dcc: // INT_SAMPLER_CUBE - return function ( t ) { + case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE - this.origin.copy( this.at( t, v1 ) ); + case 0x8dc5: + // SAMPLER_CUBE_SHADOW + return setValueT6Array; + } + } // --- Uniform Classes --- - return this; - }; + function SingleUniform(id, activeInfo, addr) { + this.id = id; + this.addr = addr; + this.cache = []; + this.setValue = getSingularSetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG + } - }(), + function PureArrayUniform(id, activeInfo, addr) { + this.id = id; + this.addr = addr; + this.cache = []; + this.size = activeInfo.size; + this.setValue = getPureArraySetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG + } + + PureArrayUniform.prototype.updateCache = function (data) { + var cache = this.cache; - closestPointToPoint: function ( point, optionalTarget ) { + if (data instanceof Float32Array && cache.length !== data.length) { + this.cache = new Float32Array(data.length); + } - var result = optionalTarget || new THREE.Vector3(); - result.subVectors( point, this.origin ); - var directionDistance = result.dot( this.direction ); + copyArray(cache, data); + }; - if ( directionDistance < 0 ) { + function StructuredUniform(id) { + this.id = id; + this.seq = []; + this.map = {}; + } - return result.copy( this.origin ); + StructuredUniform.prototype.setValue = function (gl, value, textures) { + var seq = this.seq; + for (var i = 0, n = seq.length; i !== n; ++i) { + var u = seq[i]; + u.setValue(gl, value[u.id], textures); } + }; // --- Top-level --- + // Parser - builds up the property tree from the path strings - return result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); - - }, - distanceToPoint: function () { + var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g; // extracts + // - the identifier (member name or array index) + // - followed by an optional right bracket (found when array index) + // - followed by an optional left bracket or dot (type of subscript) + // + // Note: These portions can be read in a non-overlapping fashion and + // allow straightforward parsing of the hierarchy that WebGL encodes + // in the uniform names. - var v1 = new THREE.Vector3(); + function addUniform(container, uniformObject) { + container.seq.push(uniformObject); + container.map[uniformObject.id] = uniformObject; + } - return function ( point ) { + function parseUniform(activeInfo, addr, container) { + var path = activeInfo.name, + pathLength = path.length; // reset RegExp object, because of the early exit of a previous run - var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction ); + RePathPart.lastIndex = 0; - // point behind the ray + while (true) { + var match = RePathPart.exec(path), + matchEnd = RePathPart.lastIndex; + var id = match[1]; + var idIsIndex = match[2] === ']', + subscript = match[3]; + if (idIsIndex) id = id | 0; // convert to integer - if ( directionDistance < 0 ) { + if (subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength) { + // bare name or "pure" bottom-level array "[0]" suffix + addUniform(container, subscript === undefined ? new SingleUniform(id, activeInfo, addr) : new PureArrayUniform(id, activeInfo, addr)); + break; + } else { + // step into inner node / create it in case it doesn't exist + var map = container.map; + var next = map[id]; - return this.origin.distanceTo( point ); + if (next === undefined) { + next = new StructuredUniform(id); + addUniform(container, next); + } + container = next; } + } + } // Root Container - v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); - return v1.distanceTo( point ); + function WebGLUniforms(gl, program) { + this.seq = []; + this.map = {}; + var n = gl.getProgramParameter(program, 35718); - }; + for (var i = 0; i < n; ++i) { + var info = gl.getActiveUniform(program, i), + addr = gl.getUniformLocation(program, info.name); + parseUniform(info, addr, this); + } + } - }(), + WebGLUniforms.prototype.setValue = function (gl, name, value, textures) { + var u = this.map[name]; + if (u !== undefined) u.setValue(gl, value, textures); + }; - distanceSqToSegment: function( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { + WebGLUniforms.prototype.setOptional = function (gl, object, name) { + var v = object[name]; + if (v !== undefined) this.setValue(gl, name, v); + }; // Static interface - // from http://www.geometrictools.com/LibMathematics/Distance/Wm5DistRay3Segment3.cpp - // It returns the min distance between the ray and the segment - // defined by v0 and v1 - // It can also set two optional targets : - // - The closest point on the ray - // - The closest point on the segment - var segCenter = v0.clone().add( v1 ).multiplyScalar( 0.5 ); - var segDir = v1.clone().sub( v0 ).normalize(); - var segExtent = v0.distanceTo( v1 ) * 0.5; - var diff = this.origin.clone().sub( segCenter ); - var a01 = - this.direction.dot( segDir ); - var b0 = diff.dot( this.direction ); - var b1 = - diff.dot( segDir ); - var c = diff.lengthSq(); - var det = Math.abs( 1 - a01 * a01 ); - var s0, s1, sqrDist, extDet; + WebGLUniforms.upload = function (gl, seq, values, textures) { + for (var i = 0, n = seq.length; i !== n; ++i) { + var u = seq[i], + v = values[u.id]; - if ( det >= 0 ) { - - // The ray and segment are not parallel. - - s0 = a01 * b1 - b0; - s1 = a01 * b0 - b1; - extDet = segExtent * det; - - if ( s0 >= 0 ) { + if (v.needsUpdate !== false) { + // note: always updating when .needsUpdate is undefined + u.setValue(gl, v.value, textures); + } + } + }; - if ( s1 >= - extDet ) { + WebGLUniforms.seqWithValue = function (seq, values) { + var r = []; - if ( s1 <= extDet ) { + for (var i = 0, n = seq.length; i !== n; ++i) { + var u = seq[i]; + if (u.id in values) r.push(u); + } - // region 0 - // Minimum at interior points of ray and segment. + return r; + }; - var invDet = 1 / det; - s0 *= invDet; - s1 *= invDet; - sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; + function WebGLShader(gl, type, string) { + var shader = gl.createShader(type); + gl.shaderSource(shader, string); + gl.compileShader(shader); + return shader; + } - } else { + var programIdCount = 0; - // region 1 + function addLineNumbers(string) { + var lines = string.split('\n'); - s1 = segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + for (var i = 0; i < lines.length; i++) { + lines[i] = i + 1 + ': ' + lines[i]; + } - } + return lines.join('\n'); + } - } else { + function getEncodingComponents(encoding) { + switch (encoding) { + case LinearEncoding: + return ['Linear', '( value )']; - // region 5 + case sRGBEncoding: + return ['sRGB', '( value )']; - s1 = - segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + case RGBEEncoding: + return ['RGBE', '( value )']; - } + case RGBM7Encoding: + return ['RGBM', '( value, 7.0 )']; - } else { + case RGBM16Encoding: + return ['RGBM', '( value, 16.0 )']; - if ( s1 <= - extDet) { + case RGBDEncoding: + return ['RGBD', '( value, 256.0 )']; - // region 4 + case GammaEncoding: + return ['Gamma', '( value, float( GAMMA_FACTOR ) )']; - s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + case LogLuvEncoding: + return ['LogLuv', '( value )']; - } else if ( s1 <= extDet ) { + default: + console.warn('THREE.WebGLProgram: Unsupported encoding:', encoding); + return ['Linear', '( value )']; + } + } - // region 3 + function getShaderErrors(gl, shader, type) { + var status = gl.getShaderParameter(shader, 35713); + var log = gl.getShaderInfoLog(shader).trim(); + if (status && log === '') return ''; // --enable-privileged-webgl-extension + // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); - s0 = 0; - s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = s1 * ( s1 + 2 * b1 ) + c; + var source = gl.getShaderSource(shader); + return 'THREE.WebGLShader: gl.getShaderInfoLog() ' + type + '\n' + log + addLineNumbers(source); + } - } else { + function getTexelDecodingFunction(functionName, encoding) { + var components = getEncodingComponents(encoding); + return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[0] + 'ToLinear' + components[1] + '; }'; + } - // region 2 + function getTexelEncodingFunction(functionName, encoding) { + var components = getEncodingComponents(encoding); + return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[0] + components[1] + '; }'; + } - s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + function getToneMappingFunction(functionName, toneMapping) { + var toneMappingName; - } + switch (toneMapping) { + case LinearToneMapping: + toneMappingName = 'Linear'; + break; - } + case ReinhardToneMapping: + toneMappingName = 'Reinhard'; + break; - } else { + case CineonToneMapping: + toneMappingName = 'OptimizedCineon'; + break; - // Ray and segment are parallel. + case ACESFilmicToneMapping: + toneMappingName = 'ACESFilmic'; + break; - s1 = ( a01 > 0 ) ? - segExtent : segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + case CustomToneMapping: + toneMappingName = 'Custom'; + break; + default: + console.warn('THREE.WebGLProgram: Unsupported toneMapping:', toneMapping); + toneMappingName = 'Linear'; } - if ( optionalPointOnRay ) { + return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; + } + + function generateExtensions(parameters) { + var chunks = [parameters.extensionDerivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ? '#extension GL_OES_standard_derivatives : enable' : '', (parameters.extensionFragDepth || parameters.logarithmicDepthBuffer) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '', parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ? '#extension GL_EXT_draw_buffers : require' : '', (parameters.extensionShaderTextureLOD || parameters.envMap) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : '']; + return chunks.filter(filterEmptyLine).join('\n'); + } - optionalPointOnRay.copy( this.direction.clone().multiplyScalar( s0 ).add( this.origin ) ); + function generateDefines(defines) { + var chunks = []; + for (var name in defines) { + var value = defines[name]; + if (value === false) continue; + chunks.push('#define ' + name + ' ' + value); } - if ( optionalPointOnSegment ) { + return chunks.join('\n'); + } + + function fetchAttributeLocations(gl, program) { + var attributes = {}; + var n = gl.getProgramParameter(program, 35721); - optionalPointOnSegment.copy( segDir.clone().multiplyScalar( s1 ).add( segCenter ) ); + for (var i = 0; i < n; i++) { + var info = gl.getActiveAttrib(program, i); + var name = info.name; // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); + attributes[name] = gl.getAttribLocation(program, name); } - return sqrDist; + return attributes; + } + + function filterEmptyLine(string) { + return string !== ''; + } - }, + function replaceLightNums(string, parameters) { + return string.replace(/NUM_DIR_LIGHTS/g, parameters.numDirLights).replace(/NUM_SPOT_LIGHTS/g, parameters.numSpotLights).replace(/NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g, parameters.numPointLights).replace(/NUM_HEMI_LIGHTS/g, parameters.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows); + } - isIntersectionSphere: function ( sphere ) { + function replaceClippingPlaneNums(string, parameters) { + return string.replace(/NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, parameters.numClippingPlanes - parameters.numClipIntersection); + } // Resolve Includes - return this.distanceToPoint( sphere.center ) <= sphere.radius; - }, + var includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; - isIntersectionPlane: function ( plane ) { + function resolveIncludes(string) { + return string.replace(includePattern, includeReplacer); + } - // check if the ray lies on the plane first + function includeReplacer(match, include) { + var string = ShaderChunk[include]; - var distToPoint = plane.distanceToPoint( this.origin ); + if (string === undefined) { + throw new Error('Can not resolve #include <' + include + '>'); + } - if ( distToPoint === 0 ) { + return resolveIncludes(string); + } // Unroll Loops - return true; - } + var deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; + var unrollLoopPattern = /#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g; - var denominator = plane.normal.dot( this.direction ); + function unrollLoops(string) { + return string.replace(unrollLoopPattern, loopReplacer).replace(deprecatedUnrollLoopPattern, deprecatedLoopReplacer); + } - if ( denominator * distToPoint < 0 ) { + function deprecatedLoopReplacer(match, start, end, snippet) { + console.warn('WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.'); + return loopReplacer(match, start, end, snippet); + } - return true + function loopReplacer(match, start, end, snippet) { + var string = ''; + for (var i = parseInt(start); i < parseInt(end); i++) { + string += snippet.replace(/\[\s*i\s*\]/g, '[ ' + i + ' ]').replace(/UNROLLED_LOOP_INDEX/g, i); } - // ray origin is behind the plane (and is pointing behind it) + return string; + } // - return false; - }, + function generatePrecision(parameters) { + var precisionstring = "precision " + parameters.precision + " float;\nprecision " + parameters.precision + " int;"; - distanceToPlane: function ( plane ) { + if (parameters.precision === "highp") { + precisionstring += "\n#define HIGH_PRECISION"; + } else if (parameters.precision === "mediump") { + precisionstring += "\n#define MEDIUM_PRECISION"; + } else if (parameters.precision === "lowp") { + precisionstring += "\n#define LOW_PRECISION"; + } - var denominator = plane.normal.dot( this.direction ); - if ( denominator == 0 ) { + return precisionstring; + } - // line is coplanar, return origin - if( plane.distanceToPoint( this.origin ) == 0 ) { + function generateShadowMapTypeDefine(parameters) { + var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; - return 0; + if (parameters.shadowMapType === PCFShadowMap) { + shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; + } else if (parameters.shadowMapType === PCFSoftShadowMap) { + shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; + } else if (parameters.shadowMapType === VSMShadowMap) { + shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; + } - } + return shadowMapTypeDefine; + } - // Null is preferable to undefined since undefined means.... it is undefined + function generateEnvMapTypeDefine(parameters) { + var envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; - return null; + if (parameters.envMap) { + switch (parameters.envMapMode) { + case CubeReflectionMapping: + case CubeRefractionMapping: + envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; + break; + case CubeUVReflectionMapping: + case CubeUVRefractionMapping: + envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; + break; + } } - var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; + return envMapTypeDefine; + } - // Return if the ray never intersects the plane + function generateEnvMapModeDefine(parameters) { + var envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; - return t >= 0 ? t : null; + if (parameters.envMap) { + switch (parameters.envMapMode) { + case CubeRefractionMapping: + case CubeUVRefractionMapping: + envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; + break; + } + } - }, + return envMapModeDefine; + } - intersectPlane: function ( plane, optionalTarget ) { + function generateEnvMapBlendingDefine(parameters) { + var envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; - var t = this.distanceToPlane( plane ); + if (parameters.envMap) { + switch (parameters.combine) { + case MultiplyOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; + break; - if ( t === null ) { + case MixOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; + break; - return null; + case AddOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; + break; + } } - return this.at( t, optionalTarget ); - - }, + return envMapBlendingDefine; + } - isIntersectionBox: function () { - - var v = new THREE.Vector3(); + function WebGLProgram(renderer, cacheKey, parameters, bindingStates) { + var gl = renderer.getContext(); + var defines = parameters.defines; + var vertexShader = parameters.vertexShader; + var fragmentShader = parameters.fragmentShader; + var shadowMapTypeDefine = generateShadowMapTypeDefine(parameters); + var envMapTypeDefine = generateEnvMapTypeDefine(parameters); + var envMapModeDefine = generateEnvMapModeDefine(parameters); + var envMapBlendingDefine = generateEnvMapBlendingDefine(parameters); + var gammaFactorDefine = renderer.gammaFactor > 0 ? renderer.gammaFactor : 1.0; + var customExtensions = parameters.isWebGL2 ? '' : generateExtensions(parameters); + var customDefines = generateDefines(defines); + var program = gl.createProgram(); + var prefixVertex, prefixFragment; + var versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + "\n" : ''; - return function ( box ) { + if (parameters.isRawShaderMaterial) { + prefixVertex = [customDefines].filter(filterEmptyLine).join('\n'); - return this.intersectBox( box, v ) !== null; + if (prefixVertex.length > 0) { + prefixVertex += '\n'; + } - } + prefixFragment = [customExtensions, customDefines].filter(filterEmptyLine).join('\n'); - }(), + if (prefixFragment.length > 0) { + prefixFragment += '\n'; + } + } else { + prefixVertex = [generatePrecision(parameters), '#define SHADER_NAME ' + parameters.shaderName, customDefines, parameters.instancing ? '#define USE_INSTANCING' : '', parameters.instancingColor ? '#define USE_INSTANCING_COLOR' : '', parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', '#define GAMMA_FACTOR ' + gammaFactorDefine, '#define MAX_BONES ' + parameters.maxBones, parameters.useFog && parameters.fog ? '#define USE_FOG' : '', parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.envMap ? '#define USE_ENVMAP' : '', parameters.envMap ? '#define ' + envMapModeDefine : '', parameters.lightMap ? '#define USE_LIGHTMAP' : '', parameters.aoMap ? '#define USE_AOMAP' : '', parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', parameters.normalMap && parameters.objectSpaceNormalMap ? '#define OBJECTSPACE_NORMALMAP' : '', parameters.normalMap && parameters.tangentSpaceNormalMap ? '#define TANGENTSPACE_NORMALMAP' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', parameters.vertexUvs ? '#define USE_UV' : '', parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.skinning ? '#define USE_SKINNING' : '', parameters.useVertexTexture ? '#define BONE_TEXTURE' : '', parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '', parameters.doubleSided ? '#define DOUBLE_SIDED' : '', parameters.flipSided ? '#define FLIP_SIDED' : '', parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ? '#define USE_LOGDEPTHBUF_EXT' : '', 'uniform mat4 modelMatrix;', 'uniform mat4 modelViewMatrix;', 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', 'uniform mat3 normalMatrix;', 'uniform vec3 cameraPosition;', 'uniform bool isOrthographic;', '#ifdef USE_INSTANCING', ' attribute mat4 instanceMatrix;', '#endif', '#ifdef USE_INSTANCING_COLOR', ' attribute vec3 instanceColor;', '#endif', 'attribute vec3 position;', 'attribute vec3 normal;', 'attribute vec2 uv;', '#ifdef USE_TANGENT', ' attribute vec4 tangent;', '#endif', '#ifdef USE_COLOR', ' attribute vec3 color;', '#endif', '#ifdef USE_MORPHTARGETS', ' attribute vec3 morphTarget0;', ' attribute vec3 morphTarget1;', ' attribute vec3 morphTarget2;', ' attribute vec3 morphTarget3;', ' #ifdef USE_MORPHNORMALS', ' attribute vec3 morphNormal0;', ' attribute vec3 morphNormal1;', ' attribute vec3 morphNormal2;', ' attribute vec3 morphNormal3;', ' #else', ' attribute vec3 morphTarget4;', ' attribute vec3 morphTarget5;', ' attribute vec3 morphTarget6;', ' attribute vec3 morphTarget7;', ' #endif', '#endif', '#ifdef USE_SKINNING', ' attribute vec4 skinIndex;', ' attribute vec4 skinWeight;', '#endif', '\n'].filter(filterEmptyLine).join('\n'); + prefixFragment = [customExtensions, generatePrecision(parameters), '#define SHADER_NAME ' + parameters.shaderName, customDefines, parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest + (parameters.alphaTest % 1 ? '' : '.0') : '', // add '.0' if integer + '#define GAMMA_FACTOR ' + gammaFactorDefine, parameters.useFog && parameters.fog ? '#define USE_FOG' : '', parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.matcap ? '#define USE_MATCAP' : '', parameters.envMap ? '#define USE_ENVMAP' : '', parameters.envMap ? '#define ' + envMapTypeDefine : '', parameters.envMap ? '#define ' + envMapModeDefine : '', parameters.envMap ? '#define ' + envMapBlendingDefine : '', parameters.lightMap ? '#define USE_LIGHTMAP' : '', parameters.aoMap ? '#define USE_AOMAP' : '', parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', parameters.normalMap && parameters.objectSpaceNormalMap ? '#define OBJECTSPACE_NORMALMAP' : '', parameters.normalMap && parameters.tangentSpaceNormalMap ? '#define TANGENTSPACE_NORMALMAP' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.sheen ? '#define USE_SHEEN' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '', parameters.vertexUvs ? '#define USE_UV' : '', parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.doubleSided ? '#define DOUBLE_SIDED' : '', parameters.flipSided ? '#define FLIP_SIDED' : '', parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '', parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ? '#define USE_LOGDEPTHBUF_EXT' : '', (parameters.extensionShaderTextureLOD || parameters.envMap) && parameters.rendererExtensionShaderTextureLod ? '#define TEXTURE_LOD_EXT' : '', 'uniform mat4 viewMatrix;', 'uniform vec3 cameraPosition;', 'uniform bool isOrthographic;', parameters.toneMapping !== NoToneMapping ? '#define TONE_MAPPING' : '', parameters.toneMapping !== NoToneMapping ? ShaderChunk['tonemapping_pars_fragment'] : '', // this code is required here because it is used by the toneMapping() function defined below + parameters.toneMapping !== NoToneMapping ? getToneMappingFunction('toneMapping', parameters.toneMapping) : '', parameters.dithering ? '#define DITHERING' : '', ShaderChunk['encodings_pars_fragment'], // this code is required here because it is used by the various encoding/decoding function defined below + parameters.map ? getTexelDecodingFunction('mapTexelToLinear', parameters.mapEncoding) : '', parameters.matcap ? getTexelDecodingFunction('matcapTexelToLinear', parameters.matcapEncoding) : '', parameters.envMap ? getTexelDecodingFunction('envMapTexelToLinear', parameters.envMapEncoding) : '', parameters.emissiveMap ? getTexelDecodingFunction('emissiveMapTexelToLinear', parameters.emissiveMapEncoding) : '', parameters.lightMap ? getTexelDecodingFunction('lightMapTexelToLinear', parameters.lightMapEncoding) : '', getTexelEncodingFunction('linearToOutputTexel', parameters.outputEncoding), parameters.depthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '', '\n'].filter(filterEmptyLine).join('\n'); + } + + vertexShader = resolveIncludes(vertexShader); + vertexShader = replaceLightNums(vertexShader, parameters); + vertexShader = replaceClippingPlaneNums(vertexShader, parameters); + fragmentShader = resolveIncludes(fragmentShader); + fragmentShader = replaceLightNums(fragmentShader, parameters); + fragmentShader = replaceClippingPlaneNums(fragmentShader, parameters); + vertexShader = unrollLoops(vertexShader); + fragmentShader = unrollLoops(fragmentShader); + + if (parameters.isWebGL2 && parameters.isRawShaderMaterial !== true) { + // GLSL 3.0 conversion for built-in materials and ShaderMaterial + versionString = '#version 300 es\n'; + prefixVertex = ['#define attribute in', '#define varying out', '#define texture2D texture'].join('\n') + '\n' + prefixVertex; + prefixFragment = ['#define varying in', parameters.glslVersion === GLSL3 ? '' : 'out highp vec4 pc_fragColor;', parameters.glslVersion === GLSL3 ? '' : '#define gl_FragColor pc_fragColor', '#define gl_FragDepthEXT gl_FragDepth', '#define texture2D texture', '#define textureCube texture', '#define texture2DProj textureProj', '#define texture2DLodEXT textureLod', '#define texture2DProjLodEXT textureProjLod', '#define textureCubeLodEXT textureLod', '#define texture2DGradEXT textureGrad', '#define texture2DProjGradEXT textureProjGrad', '#define textureCubeGradEXT textureGrad'].join('\n') + '\n' + prefixFragment; + } + + var vertexGlsl = versionString + prefixVertex + vertexShader; + var fragmentGlsl = versionString + prefixFragment + fragmentShader; // console.log( '*VERTEX*', vertexGlsl ); + // console.log( '*FRAGMENT*', fragmentGlsl ); + + var glVertexShader = WebGLShader(gl, 35633, vertexGlsl); + var glFragmentShader = WebGLShader(gl, 35632, fragmentGlsl); + gl.attachShader(program, glVertexShader); + gl.attachShader(program, glFragmentShader); // Force a particular attribute to index 0. + + if (parameters.index0AttributeName !== undefined) { + gl.bindAttribLocation(program, 0, parameters.index0AttributeName); + } else if (parameters.morphTargets === true) { + // programs with morphTargets displace position out of attribute 0 + gl.bindAttribLocation(program, 0, 'position'); + } + + gl.linkProgram(program); // check for link errors + + if (renderer.debug.checkShaderErrors) { + var programLog = gl.getProgramInfoLog(program).trim(); + var vertexLog = gl.getShaderInfoLog(glVertexShader).trim(); + var fragmentLog = gl.getShaderInfoLog(glFragmentShader).trim(); + var runnable = true; + var haveDiagnostics = true; + + if (gl.getProgramParameter(program, 35714) === false) { + runnable = false; + var vertexErrors = getShaderErrors(gl, glVertexShader, 'vertex'); + var fragmentErrors = getShaderErrors(gl, glFragmentShader, 'fragment'); + console.error('THREE.WebGLProgram: shader error: ', gl.getError(), '35715', gl.getProgramParameter(program, 35715), 'gl.getProgramInfoLog', programLog, vertexErrors, fragmentErrors); + } else if (programLog !== '') { + console.warn('THREE.WebGLProgram: gl.getProgramInfoLog()', programLog); + } else if (vertexLog === '' || fragmentLog === '') { + haveDiagnostics = false; + } + + if (haveDiagnostics) { + this.diagnostics = { + runnable: runnable, + programLog: programLog, + vertexShader: { + log: vertexLog, + prefix: prefixVertex + }, + fragmentShader: { + log: fragmentLog, + prefix: prefixFragment + } + }; + } + } // Clean up + // Crashes in iOS9 and iOS10. #18402 + // gl.detachShader( program, glVertexShader ); + // gl.detachShader( program, glFragmentShader ); - intersectBox: function ( box , optionalTarget ) { - // http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-7-intersecting-simple-shapes/ray-box-intersection/ + gl.deleteShader(glVertexShader); + gl.deleteShader(glFragmentShader); // set up caching for uniform locations - var tmin,tmax,tymin,tymax,tzmin,tzmax; + var cachedUniforms; - var invdirx = 1/this.direction.x, - invdiry = 1/this.direction.y, - invdirz = 1/this.direction.z; + this.getUniforms = function () { + if (cachedUniforms === undefined) { + cachedUniforms = new WebGLUniforms(gl, program); + } - var origin = this.origin; + return cachedUniforms; + }; // set up caching for attribute locations - if (invdirx >= 0) { - - tmin = (box.min.x - origin.x) * invdirx; - tmax = (box.max.x - origin.x) * invdirx; - } else { + var cachedAttributes; - tmin = (box.max.x - origin.x) * invdirx; - tmax = (box.min.x - origin.x) * invdirx; - } + this.getAttributes = function () { + if (cachedAttributes === undefined) { + cachedAttributes = fetchAttributeLocations(gl, program); + } - if (invdiry >= 0) { - - tymin = (box.min.y - origin.y) * invdiry; - tymax = (box.max.y - origin.y) * invdiry; + return cachedAttributes; + }; // free resource - } else { - tymin = (box.max.y - origin.y) * invdiry; - tymax = (box.min.y - origin.y) * invdiry; - } + this.destroy = function () { + bindingStates.releaseStatesOfProgram(this); + gl.deleteProgram(program); + this.program = undefined; + }; // - if ((tmin > tymax) || (tymin > tmax)) return null; - // These lines also handle the case where tmin or tmax is NaN - // (result of 0 * Infinity). x !== x returns true if x is NaN - - if (tymin > tmin || tmin !== tmin ) tmin = tymin; + this.name = parameters.shaderName; + this.id = programIdCount++; + this.cacheKey = cacheKey; + this.usedTimes = 1; + this.program = program; + this.vertexShader = glVertexShader; + this.fragmentShader = glFragmentShader; + return this; + } - if (tymax < tmax || tmax !== tmax ) tmax = tymax; + function WebGLPrograms(renderer, cubemaps, extensions, capabilities, bindingStates, clipping) { + var programs = []; + var isWebGL2 = capabilities.isWebGL2; + var logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; + var floatVertexTextures = capabilities.floatVertexTextures; + var maxVertexUniforms = capabilities.maxVertexUniforms; + var vertexTextures = capabilities.vertexTextures; + var precision = capabilities.precision; + var shaderIDs = { + MeshDepthMaterial: 'depth', + MeshDistanceMaterial: 'distanceRGBA', + MeshNormalMaterial: 'normal', + MeshBasicMaterial: 'basic', + MeshLambertMaterial: 'lambert', + MeshPhongMaterial: 'phong', + MeshToonMaterial: 'toon', + MeshStandardMaterial: 'physical', + MeshPhysicalMaterial: 'physical', + MeshMatcapMaterial: 'matcap', + LineBasicMaterial: 'basic', + LineDashedMaterial: 'dashed', + PointsMaterial: 'points', + ShadowMaterial: 'shadow', + SpriteMaterial: 'sprite' + }; + var parameterNames = ["precision", "isWebGL2", "supportsVertexTextures", "outputEncoding", "instancing", "instancingColor", "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", "envMapCubeUV", "lightMap", "lightMapEncoding", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatMap", "clearcoatRoughnessMap", "clearcoatNormalMap", "displacementMap", "specularMap", "roughnessMap", "metalnessMap", "gradientMap", "alphaMap", "combine", "vertexColors", "vertexTangents", "vertexUvs", "uvsVertexOnly", "fog", "useFog", "fogExp2", "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", "maxBones", "useVertexTexture", "morphTargets", "morphNormals", "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights", "numDirLightShadows", "numPointLightShadows", "numSpotLightShadows", "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights', "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering", "sheen", "transmissionMap"]; - if (invdirz >= 0) { - - tzmin = (box.min.z - origin.z) * invdirz; - tzmax = (box.max.z - origin.z) * invdirz; + function getMaxBones(object) { + var skeleton = object.skeleton; + var bones = skeleton.bones; - } else { + if (floatVertexTextures) { + return 1024; + } else { + // default for when object is not specified + // ( for example when prebuilding shader to be used with multiple objects ) + // + // - leave some extra space for other uniforms + // - limit here is ANGLE's 254 max uniform vectors + // (up to 54 should be safe) + var nVertexUniforms = maxVertexUniforms; + var nVertexMatrices = Math.floor((nVertexUniforms - 20) / 4); + var maxBones = Math.min(nVertexMatrices, bones.length); + + if (maxBones < bones.length) { + console.warn('THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.'); + return 0; + } - tzmin = (box.max.z - origin.z) * invdirz; - tzmax = (box.min.z - origin.z) * invdirz; + return maxBones; + } } - if ((tmin > tzmax) || (tzmin > tmax)) return null; + function getTextureEncodingFromMap(map) { + var encoding; - if (tzmin > tmin || tmin !== tmin ) tmin = tzmin; - - if (tzmax < tmax || tmax !== tmax ) tmax = tzmax; + if (!map) { + encoding = LinearEncoding; + } else if (map.isTexture) { + encoding = map.encoding; + } else if (map.isWebGLRenderTarget) { + console.warn("THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead."); + encoding = map.texture.encoding; + } - //return point closest to the ray (positive side) + return encoding; + } - if ( tmax < 0 ) return null; + function getParameters(material, lights, shadows, scene, object) { + var fog = scene.fog; + var environment = material.isMeshStandardMaterial ? scene.environment : null; + var envMap = cubemaps.get(material.envMap || environment); + var shaderID = shaderIDs[material.type]; // heuristics to create shader parameters according to lights in the scene + // (not to blow over maxLights budget) - return this.at( tmin >= 0 ? tmin : tmax, optionalTarget ); + var maxBones = object.isSkinnedMesh ? getMaxBones(object) : 0; - }, + if (material.precision !== null) { + precision = capabilities.getMaxPrecision(material.precision); - intersectTriangle: function() { + if (precision !== material.precision) { + console.warn('THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.'); + } + } - // Compute the offset origin, edges, and normal. - var diff = new THREE.Vector3(); - var edge1 = new THREE.Vector3(); - var edge2 = new THREE.Vector3(); - var normal = new THREE.Vector3(); + var vertexShader, fragmentShader; - return function ( a, b, c, backfaceCulling, optionalTarget ) { + if (shaderID) { + var shader = ShaderLib[shaderID]; + vertexShader = shader.vertexShader; + fragmentShader = shader.fragmentShader; + } else { + vertexShader = material.vertexShader; + fragmentShader = material.fragmentShader; + } + + var currentRenderTarget = renderer.getRenderTarget(); + var parameters = { + isWebGL2: isWebGL2, + shaderID: shaderID, + shaderName: material.type, + vertexShader: vertexShader, + fragmentShader: fragmentShader, + defines: material.defines, + isRawShaderMaterial: material.isRawShaderMaterial === true, + glslVersion: material.glslVersion, + precision: precision, + instancing: object.isInstancedMesh === true, + instancingColor: object.isInstancedMesh === true && object.instanceColor !== null, + supportsVertexTextures: vertexTextures, + outputEncoding: currentRenderTarget !== null ? getTextureEncodingFromMap(currentRenderTarget.texture) : renderer.outputEncoding, + map: !!material.map, + mapEncoding: getTextureEncodingFromMap(material.map), + matcap: !!material.matcap, + matcapEncoding: getTextureEncodingFromMap(material.matcap), + envMap: !!envMap, + envMapMode: envMap && envMap.mapping, + envMapEncoding: getTextureEncodingFromMap(envMap), + envMapCubeUV: !!envMap && (envMap.mapping === CubeUVReflectionMapping || envMap.mapping === CubeUVRefractionMapping), + lightMap: !!material.lightMap, + lightMapEncoding: getTextureEncodingFromMap(material.lightMap), + aoMap: !!material.aoMap, + emissiveMap: !!material.emissiveMap, + emissiveMapEncoding: getTextureEncodingFromMap(material.emissiveMap), + bumpMap: !!material.bumpMap, + normalMap: !!material.normalMap, + objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap, + tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap, + clearcoatMap: !!material.clearcoatMap, + clearcoatRoughnessMap: !!material.clearcoatRoughnessMap, + clearcoatNormalMap: !!material.clearcoatNormalMap, + displacementMap: !!material.displacementMap, + roughnessMap: !!material.roughnessMap, + metalnessMap: !!material.metalnessMap, + specularMap: !!material.specularMap, + alphaMap: !!material.alphaMap, + gradientMap: !!material.gradientMap, + sheen: !!material.sheen, + transmissionMap: !!material.transmissionMap, + combine: material.combine, + vertexTangents: material.normalMap && material.vertexTangents, + vertexColors: material.vertexColors, + vertexUvs: !!material.map || !!material.bumpMap || !!material.normalMap || !!material.specularMap || !!material.alphaMap || !!material.emissiveMap || !!material.roughnessMap || !!material.metalnessMap || !!material.clearcoatMap || !!material.clearcoatRoughnessMap || !!material.clearcoatNormalMap || !!material.displacementMap || !!material.transmissionMap, + uvsVertexOnly: !(!!material.map || !!material.bumpMap || !!material.normalMap || !!material.specularMap || !!material.alphaMap || !!material.emissiveMap || !!material.roughnessMap || !!material.metalnessMap || !!material.clearcoatNormalMap || !!material.transmissionMap) && !!material.displacementMap, + fog: !!fog, + useFog: material.fog, + fogExp2: fog && fog.isFogExp2, + flatShading: material.flatShading, + sizeAttenuation: material.sizeAttenuation, + logarithmicDepthBuffer: logarithmicDepthBuffer, + skinning: material.skinning && maxBones > 0, + maxBones: maxBones, + useVertexTexture: floatVertexTextures, + morphTargets: material.morphTargets, + morphNormals: material.morphNormals, + maxMorphTargets: renderer.maxMorphTargets, + maxMorphNormals: renderer.maxMorphNormals, + numDirLights: lights.directional.length, + numPointLights: lights.point.length, + numSpotLights: lights.spot.length, + numRectAreaLights: lights.rectArea.length, + numHemiLights: lights.hemi.length, + numDirLightShadows: lights.directionalShadowMap.length, + numPointLightShadows: lights.pointShadowMap.length, + numSpotLightShadows: lights.spotShadowMap.length, + numClippingPlanes: clipping.numPlanes, + numClipIntersection: clipping.numIntersection, + dithering: material.dithering, + shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0, + shadowMapType: renderer.shadowMap.type, + toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping, + physicallyCorrectLights: renderer.physicallyCorrectLights, + premultipliedAlpha: material.premultipliedAlpha, + alphaTest: material.alphaTest, + doubleSided: material.side === DoubleSide, + flipSided: material.side === BackSide, + depthPacking: material.depthPacking !== undefined ? material.depthPacking : false, + index0AttributeName: material.index0AttributeName, + extensionDerivatives: material.extensions && material.extensions.derivatives, + extensionFragDepth: material.extensions && material.extensions.fragDepth, + extensionDrawBuffers: material.extensions && material.extensions.drawBuffers, + extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD, + rendererExtensionFragDepth: isWebGL2 || extensions.has('EXT_frag_depth'), + rendererExtensionDrawBuffers: isWebGL2 || extensions.has('WEBGL_draw_buffers'), + rendererExtensionShaderTextureLod: isWebGL2 || extensions.has('EXT_shader_texture_lod'), + customProgramCacheKey: material.customProgramCacheKey() + }; + return parameters; + } - // from http://www.geometrictools.com/LibMathematics/Intersection/Wm5IntrRay3Triangle3.cpp + function getProgramCacheKey(parameters) { + var array = []; - edge1.subVectors( b, a ); - edge2.subVectors( c, a ); - normal.crossVectors( edge1, edge2 ); + if (parameters.shaderID) { + array.push(parameters.shaderID); + } else { + array.push(parameters.fragmentShader); + array.push(parameters.vertexShader); + } - // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, - // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by - // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) - // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) - // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) - var DdN = this.direction.dot( normal ); - var sign; + if (parameters.defines !== undefined) { + for (var name in parameters.defines) { + array.push(name); + array.push(parameters.defines[name]); + } + } - if ( DdN > 0 ) { + if (parameters.isRawShaderMaterial === false) { + for (var i = 0; i < parameterNames.length; i++) { + array.push(parameters[parameterNames[i]]); + } - if ( backfaceCulling ) return null; - sign = 1; + array.push(renderer.outputEncoding); + array.push(renderer.gammaFactor); + } - } else if ( DdN < 0 ) { + array.push(parameters.customProgramCacheKey); + return array.join(); + } - sign = - 1; - DdN = - DdN; + function getUniforms(material) { + var shaderID = shaderIDs[material.type]; + var uniforms; + if (shaderID) { + var shader = ShaderLib[shaderID]; + uniforms = UniformsUtils.clone(shader.uniforms); } else { - - return null; - + uniforms = material.uniforms; } - diff.subVectors( this.origin, a ); - var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) ); + return uniforms; + } - // b1 < 0, no intersection - if ( DdQxE2 < 0 ) { + function acquireProgram(parameters, cacheKey) { + var program; // Check if code has been already compiled - return null; + for (var p = 0, pl = programs.length; p < pl; p++) { + var preexistingProgram = programs[p]; + if (preexistingProgram.cacheKey === cacheKey) { + program = preexistingProgram; + ++program.usedTimes; + break; + } } - var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) ); - - // b2 < 0, no intersection - if ( DdE1xQ < 0 ) { - - return null; - + if (program === undefined) { + program = new WebGLProgram(renderer, cacheKey, parameters, bindingStates); + programs.push(program); } - // b1+b2 > 1, no intersection - if ( DdQxE2 + DdE1xQ > DdN ) { + return program; + } - return null; + function releaseProgram(program) { + if (--program.usedTimes === 0) { + // Remove from unordered set + var i = programs.indexOf(program); + programs[i] = programs[programs.length - 1]; + programs.pop(); // Free WebGL resources + program.destroy(); } + } - // Line intersects triangle, check if ray does. - var QdN = - sign * diff.dot( normal ); + return { + getParameters: getParameters, + getProgramCacheKey: getProgramCacheKey, + getUniforms: getUniforms, + acquireProgram: acquireProgram, + releaseProgram: releaseProgram, + // Exposed for resource monitoring & error feedback via renderer.info: + programs: programs + }; + } - // t < 0, no intersection - if ( QdN < 0 ) { + function WebGLProperties() { + var properties = new WeakMap(); - return null; + function get(object) { + var map = properties.get(object); + if (map === undefined) { + map = {}; + properties.set(object, map); } - // Ray intersects triangle. - return this.at( QdN / DdN, optionalTarget ); - + return map; } - - }(), - applyMatrix4: function ( matrix4 ) { + function remove(object) { + properties.delete(object); + } - this.direction.add( this.origin ).applyMatrix4( matrix4 ); - this.origin.applyMatrix4( matrix4 ); - this.direction.sub( this.origin ); - this.direction.normalize(); + function update(object, key, value) { + properties.get(object)[key] = value; + } - return this; - }, + function dispose() { + properties = new WeakMap(); + } - equals: function ( ray ) { + return { + get: get, + remove: remove, + update: update, + dispose: dispose + }; + } - return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); + function painterSortStable(a, b) { + if (a.groupOrder !== b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder !== b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else if (a.program !== b.program) { + return a.program.id - b.program.id; + } else if (a.material.id !== b.material.id) { + return a.material.id - b.material.id; + } else if (a.z !== b.z) { + return a.z - b.z; + } else { + return a.id - b.id; + } + } - }, + function reversePainterSortStable(a, b) { + if (a.groupOrder !== b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder !== b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else if (a.z !== b.z) { + return b.z - a.z; + } else { + return a.id - b.id; + } + } - clone: function () { + function WebGLRenderList(properties) { + var renderItems = []; + var renderItemsIndex = 0; + var opaque = []; + var transparent = []; + var defaultProgram = { + id: -1 + }; - return new THREE.Ray().copy( this ); + function init() { + renderItemsIndex = 0; + opaque.length = 0; + transparent.length = 0; + } + + function getNextRenderItem(object, geometry, material, groupOrder, z, group) { + var renderItem = renderItems[renderItemsIndex]; + var materialProperties = properties.get(material); + + if (renderItem === undefined) { + renderItem = { + id: object.id, + object: object, + geometry: geometry, + material: material, + program: materialProperties.program || defaultProgram, + groupOrder: groupOrder, + renderOrder: object.renderOrder, + z: z, + group: group + }; + renderItems[renderItemsIndex] = renderItem; + } else { + renderItem.id = object.id; + renderItem.object = object; + renderItem.geometry = geometry; + renderItem.material = material; + renderItem.program = materialProperties.program || defaultProgram; + renderItem.groupOrder = groupOrder; + renderItem.renderOrder = object.renderOrder; + renderItem.z = z; + renderItem.group = group; + } - } + renderItemsIndex++; + return renderItem; + } -}; + function push(object, geometry, material, groupOrder, z, group) { + var renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); + (material.transparent === true ? transparent : opaque).push(renderItem); + } -/** - * @author bhouston / http://exocortex.com - * @author mrdoob / http://mrdoob.com/ - */ + function unshift(object, geometry, material, groupOrder, z, group) { + var renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); + (material.transparent === true ? transparent : opaque).unshift(renderItem); + } -THREE.Sphere = function ( center, radius ) { + function sort(customOpaqueSort, customTransparentSort) { + if (opaque.length > 1) opaque.sort(customOpaqueSort || painterSortStable); + if (transparent.length > 1) transparent.sort(customTransparentSort || reversePainterSortStable); + } - this.center = ( center !== undefined ) ? center : new THREE.Vector3(); - this.radius = ( radius !== undefined ) ? radius : 0; + function finish() { + // Clear references from inactive renderItems in the list + for (var i = renderItemsIndex, il = renderItems.length; i < il; i++) { + var renderItem = renderItems[i]; + if (renderItem.id === null) break; + renderItem.id = null; + renderItem.object = null; + renderItem.geometry = null; + renderItem.material = null; + renderItem.program = null; + renderItem.group = null; + } + } -}; + return { + opaque: opaque, + transparent: transparent, + init: init, + push: push, + unshift: unshift, + finish: finish, + sort: sort + }; + } -THREE.Sphere.prototype = { + function WebGLRenderLists(properties) { + var lists = new WeakMap(); - constructor: THREE.Sphere, + function get(scene, camera) { + var cameras = lists.get(scene); + var list; - set: function ( center, radius ) { + if (cameras === undefined) { + list = new WebGLRenderList(properties); + lists.set(scene, new WeakMap()); + lists.get(scene).set(camera, list); + } else { + list = cameras.get(camera); - this.center.copy( center ); - this.radius = radius; + if (list === undefined) { + list = new WebGLRenderList(properties); + cameras.set(camera, list); + } + } - return this; - }, + return list; + } + function dispose() { + lists = new WeakMap(); + } - setFromPoints: function () { + return { + get: get, + dispose: dispose + }; + } - var box = new THREE.Box3(); + function UniformsCache() { + var lights = {}; + return { + get: function get(light) { + if (lights[light.id] !== undefined) { + return lights[light.id]; + } - return function ( points, optionalCenter ) { + var uniforms; - var center = this.center; + switch (light.type) { + case 'DirectionalLight': + uniforms = { + direction: new Vector3(), + color: new Color() + }; + break; - if ( optionalCenter !== undefined ) { + case 'SpotLight': + uniforms = { + position: new Vector3(), + direction: new Vector3(), + color: new Color(), + distance: 0, + coneCos: 0, + penumbraCos: 0, + decay: 0 + }; + break; - center.copy( optionalCenter ); + case 'PointLight': + uniforms = { + position: new Vector3(), + color: new Color(), + distance: 0, + decay: 0 + }; + break; - } else { + case 'HemisphereLight': + uniforms = { + direction: new Vector3(), + skyColor: new Color(), + groundColor: new Color() + }; + break; - box.setFromPoints( points ).center( center ); + case 'RectAreaLight': + uniforms = { + color: new Color(), + position: new Vector3(), + halfWidth: new Vector3(), + halfHeight: new Vector3() + }; + break; + } + lights[light.id] = uniforms; + return uniforms; } + }; + } - var maxRadiusSq = 0; + function ShadowUniformsCache() { + var lights = {}; + return { + get: function get(light) { + if (lights[light.id] !== undefined) { + return lights[light.id]; + } - for ( var i = 0, il = points.length; i < il; i ++ ) { + var uniforms; - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); + switch (light.type) { + case 'DirectionalLight': + uniforms = { + shadowBias: 0, + shadowNormalBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; - } + case 'SpotLight': + uniforms = { + shadowBias: 0, + shadowNormalBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; - this.radius = Math.sqrt( maxRadiusSq ); + case 'PointLight': + uniforms = { + shadowBias: 0, + shadowNormalBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2(), + shadowCameraNear: 1, + shadowCameraFar: 1000 + }; + break; + // TODO (abelnation): set RectAreaLight shadow uniforms + } - return this; - - }; + lights[light.id] = uniforms; + return uniforms; + } + }; + } - }(), + var nextVersion = 0; + + function shadowCastingLightsFirst(lightA, lightB) { + return (lightB.castShadow ? 1 : 0) - (lightA.castShadow ? 1 : 0); + } + + function WebGLLights(extensions, capabilities) { + var cache = new UniformsCache(); + var shadowCache = ShadowUniformsCache(); + var state = { + version: 0, + hash: { + directionalLength: -1, + pointLength: -1, + spotLength: -1, + rectAreaLength: -1, + hemiLength: -1, + numDirectionalShadows: -1, + numPointShadows: -1, + numSpotShadows: -1 + }, + ambient: [0, 0, 0], + probe: [], + directional: [], + directionalShadow: [], + directionalShadowMap: [], + directionalShadowMatrix: [], + spot: [], + spotShadow: [], + spotShadowMap: [], + spotShadowMatrix: [], + rectArea: [], + rectAreaLTC1: null, + rectAreaLTC2: null, + point: [], + pointShadow: [], + pointShadowMap: [], + pointShadowMatrix: [], + hemi: [] + }; - copy: function ( sphere ) { + for (var i = 0; i < 9; i++) { + state.probe.push(new Vector3()); + } + + var vector3 = new Vector3(); + var matrix4 = new Matrix4(); + var matrix42 = new Matrix4(); + + function setup(lights, shadows, camera) { + var r = 0, + g = 0, + b = 0; + + for (var _i = 0; _i < 9; _i++) { + state.probe[_i].set(0, 0, 0); + } + + var directionalLength = 0; + var pointLength = 0; + var spotLength = 0; + var rectAreaLength = 0; + var hemiLength = 0; + var numDirectionalShadows = 0; + var numPointShadows = 0; + var numSpotShadows = 0; + var viewMatrix = camera.matrixWorldInverse; + lights.sort(shadowCastingLightsFirst); + + for (var _i2 = 0, l = lights.length; _i2 < l; _i2++) { + var light = lights[_i2]; + var color = light.color; + var intensity = light.intensity; + var distance = light.distance; + var shadowMap = light.shadow && light.shadow.map ? light.shadow.map.texture : null; + + if (light.isAmbientLight) { + r += color.r * intensity; + g += color.g * intensity; + b += color.b * intensity; + } else if (light.isLightProbe) { + for (var j = 0; j < 9; j++) { + state.probe[j].addScaledVector(light.sh.coefficients[j], intensity); + } + } else if (light.isDirectionalLight) { + var uniforms = cache.get(light); + uniforms.color.copy(light.color).multiplyScalar(light.intensity); + uniforms.direction.setFromMatrixPosition(light.matrixWorld); + vector3.setFromMatrixPosition(light.target.matrixWorld); + uniforms.direction.sub(vector3); + uniforms.direction.transformDirection(viewMatrix); + + if (light.castShadow) { + var shadow = light.shadow; + var shadowUniforms = shadowCache.get(light); + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowNormalBias = shadow.normalBias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; + state.directionalShadow[directionalLength] = shadowUniforms; + state.directionalShadowMap[directionalLength] = shadowMap; + state.directionalShadowMatrix[directionalLength] = light.shadow.matrix; + numDirectionalShadows++; + } - this.center.copy( sphere.center ); - this.radius = sphere.radius; + state.directional[directionalLength] = uniforms; + directionalLength++; + } else if (light.isSpotLight) { + var _uniforms = cache.get(light); - return this; + _uniforms.position.setFromMatrixPosition(light.matrixWorld); - }, + _uniforms.position.applyMatrix4(viewMatrix); - empty: function () { + _uniforms.color.copy(color).multiplyScalar(intensity); - return ( this.radius <= 0 ); + _uniforms.distance = distance; - }, + _uniforms.direction.setFromMatrixPosition(light.matrixWorld); - containsPoint: function ( point ) { + vector3.setFromMatrixPosition(light.target.matrixWorld); - return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); + _uniforms.direction.sub(vector3); - }, + _uniforms.direction.transformDirection(viewMatrix); - distanceToPoint: function ( point ) { + _uniforms.coneCos = Math.cos(light.angle); + _uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra)); + _uniforms.decay = light.decay; - return ( point.distanceTo( this.center ) - this.radius ); + if (light.castShadow) { + var _shadow = light.shadow; - }, + var _shadowUniforms = shadowCache.get(light); - intersectsSphere: function ( sphere ) { + _shadowUniforms.shadowBias = _shadow.bias; + _shadowUniforms.shadowNormalBias = _shadow.normalBias; + _shadowUniforms.shadowRadius = _shadow.radius; + _shadowUniforms.shadowMapSize = _shadow.mapSize; + state.spotShadow[spotLength] = _shadowUniforms; + state.spotShadowMap[spotLength] = shadowMap; + state.spotShadowMatrix[spotLength] = light.shadow.matrix; + numSpotShadows++; + } - var radiusSum = this.radius + sphere.radius; + state.spot[spotLength] = _uniforms; + spotLength++; + } else if (light.isRectAreaLight) { + var _uniforms2 = cache.get(light); // (a) intensity is the total visible light emitted + //uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) ); + // (b) intensity is the brightness of the light - return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); - }, + _uniforms2.color.copy(color).multiplyScalar(intensity); - clampPoint: function ( point, optionalTarget ) { + _uniforms2.position.setFromMatrixPosition(light.matrixWorld); - var deltaLengthSq = this.center.distanceToSquared( point ); + _uniforms2.position.applyMatrix4(viewMatrix); // extract local rotation of light to derive width/height half vectors - var result = optionalTarget || new THREE.Vector3(); - result.copy( point ); - if ( deltaLengthSq > ( this.radius * this.radius ) ) { + matrix42.identity(); + matrix4.copy(light.matrixWorld); + matrix4.premultiply(viewMatrix); + matrix42.extractRotation(matrix4); - result.sub( this.center ).normalize(); - result.multiplyScalar( this.radius ).add( this.center ); + _uniforms2.halfWidth.set(light.width * 0.5, 0.0, 0.0); - } + _uniforms2.halfHeight.set(0.0, light.height * 0.5, 0.0); - return result; + _uniforms2.halfWidth.applyMatrix4(matrix42); - }, + _uniforms2.halfHeight.applyMatrix4(matrix42); // TODO (abelnation): RectAreaLight distance? + // uniforms.distance = distance; - getBoundingBox: function ( optionalTarget ) { - var box = optionalTarget || new THREE.Box3(); + state.rectArea[rectAreaLength] = _uniforms2; + rectAreaLength++; + } else if (light.isPointLight) { + var _uniforms3 = cache.get(light); - box.set( this.center, this.center ); - box.expandByScalar( this.radius ); + _uniforms3.position.setFromMatrixPosition(light.matrixWorld); - return box; + _uniforms3.position.applyMatrix4(viewMatrix); - }, + _uniforms3.color.copy(light.color).multiplyScalar(light.intensity); - applyMatrix4: function ( matrix ) { + _uniforms3.distance = light.distance; + _uniforms3.decay = light.decay; - this.center.applyMatrix4( matrix ); - this.radius = this.radius * matrix.getMaxScaleOnAxis(); + if (light.castShadow) { + var _shadow2 = light.shadow; - return this; + var _shadowUniforms2 = shadowCache.get(light); - }, + _shadowUniforms2.shadowBias = _shadow2.bias; + _shadowUniforms2.shadowNormalBias = _shadow2.normalBias; + _shadowUniforms2.shadowRadius = _shadow2.radius; + _shadowUniforms2.shadowMapSize = _shadow2.mapSize; + _shadowUniforms2.shadowCameraNear = _shadow2.camera.near; + _shadowUniforms2.shadowCameraFar = _shadow2.camera.far; + state.pointShadow[pointLength] = _shadowUniforms2; + state.pointShadowMap[pointLength] = shadowMap; + state.pointShadowMatrix[pointLength] = light.shadow.matrix; + numPointShadows++; + } - translate: function ( offset ) { + state.point[pointLength] = _uniforms3; + pointLength++; + } else if (light.isHemisphereLight) { + var _uniforms4 = cache.get(light); - this.center.add( offset ); + _uniforms4.direction.setFromMatrixPosition(light.matrixWorld); - return this; + _uniforms4.direction.transformDirection(viewMatrix); - }, + _uniforms4.direction.normalize(); - equals: function ( sphere ) { + _uniforms4.skyColor.copy(light.color).multiplyScalar(intensity); - return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); + _uniforms4.groundColor.copy(light.groundColor).multiplyScalar(intensity); - }, + state.hemi[hemiLength] = _uniforms4; + hemiLength++; + } + } - clone: function () { + if (rectAreaLength > 0) { + if (capabilities.isWebGL2) { + // WebGL 2 + state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; + state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; + } else { + // WebGL 1 + if (extensions.has('OES_texture_float_linear') === true) { + state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; + state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; + } else if (extensions.has('OES_texture_half_float_linear') === true) { + state.rectAreaLTC1 = UniformsLib.LTC_HALF_1; + state.rectAreaLTC2 = UniformsLib.LTC_HALF_2; + } else { + console.error('THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.'); + } + } + } - return new THREE.Sphere().copy( this ); + state.ambient[0] = r; + state.ambient[1] = g; + state.ambient[2] = b; + var hash = state.hash; + + if (hash.directionalLength !== directionalLength || hash.pointLength !== pointLength || hash.spotLength !== spotLength || hash.rectAreaLength !== rectAreaLength || hash.hemiLength !== hemiLength || hash.numDirectionalShadows !== numDirectionalShadows || hash.numPointShadows !== numPointShadows || hash.numSpotShadows !== numSpotShadows) { + state.directional.length = directionalLength; + state.spot.length = spotLength; + state.rectArea.length = rectAreaLength; + state.point.length = pointLength; + state.hemi.length = hemiLength; + state.directionalShadow.length = numDirectionalShadows; + state.directionalShadowMap.length = numDirectionalShadows; + state.pointShadow.length = numPointShadows; + state.pointShadowMap.length = numPointShadows; + state.spotShadow.length = numSpotShadows; + state.spotShadowMap.length = numSpotShadows; + state.directionalShadowMatrix.length = numDirectionalShadows; + state.pointShadowMatrix.length = numPointShadows; + state.spotShadowMatrix.length = numSpotShadows; + hash.directionalLength = directionalLength; + hash.pointLength = pointLength; + hash.spotLength = spotLength; + hash.rectAreaLength = rectAreaLength; + hash.hemiLength = hemiLength; + hash.numDirectionalShadows = numDirectionalShadows; + hash.numPointShadows = numPointShadows; + hash.numSpotShadows = numSpotShadows; + state.version = nextVersion++; + } + } + return { + setup: setup, + state: state + }; } -}; + function WebGLRenderState(extensions, capabilities) { + var lights = new WebGLLights(extensions, capabilities); + var lightsArray = []; + var shadowsArray = []; + + function init() { + lightsArray.length = 0; + shadowsArray.length = 0; + } -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author bhouston / http://exocortex.com - */ + function pushLight(light) { + lightsArray.push(light); + } -THREE.Frustum = function ( p0, p1, p2, p3, p4, p5 ) { + function pushShadow(shadowLight) { + shadowsArray.push(shadowLight); + } - this.planes = [ + function setupLights(camera) { + lights.setup(lightsArray, shadowsArray, camera); + } - ( p0 !== undefined ) ? p0 : new THREE.Plane(), - ( p1 !== undefined ) ? p1 : new THREE.Plane(), - ( p2 !== undefined ) ? p2 : new THREE.Plane(), - ( p3 !== undefined ) ? p3 : new THREE.Plane(), - ( p4 !== undefined ) ? p4 : new THREE.Plane(), - ( p5 !== undefined ) ? p5 : new THREE.Plane() + var state = { + lightsArray: lightsArray, + shadowsArray: shadowsArray, + lights: lights + }; + return { + init: init, + state: state, + setupLights: setupLights, + pushLight: pushLight, + pushShadow: pushShadow + }; + } - ]; + function WebGLRenderStates(extensions, capabilities) { + var renderStates = new WeakMap(); -}; + function get(scene, camera) { + var renderState; -THREE.Frustum.prototype = { + if (renderStates.has(scene) === false) { + renderState = new WebGLRenderState(extensions, capabilities); + renderStates.set(scene, new WeakMap()); + renderStates.get(scene).set(camera, renderState); + } else { + if (renderStates.get(scene).has(camera) === false) { + renderState = new WebGLRenderState(extensions, capabilities); + renderStates.get(scene).set(camera, renderState); + } else { + renderState = renderStates.get(scene).get(camera); + } + } - constructor: THREE.Frustum, + return renderState; + } - set: function ( p0, p1, p2, p3, p4, p5 ) { + function dispose() { + renderStates = new WeakMap(); + } - var planes = this.planes; + return { + get: get, + dispose: dispose + }; + } - planes[0].copy( p0 ); - planes[1].copy( p1 ); - planes[2].copy( p2 ); - planes[3].copy( p3 ); - planes[4].copy( p4 ); - planes[5].copy( p5 ); + /** + * parameters = { + * + * opacity: , + * + * map: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * wireframe: , + * wireframeLinewidth: + * } + */ + function MeshDepthMaterial(parameters) { + Material.call(this); + this.type = 'MeshDepthMaterial'; + this.depthPacking = BasicDepthPacking; + this.skinning = false; + this.morphTargets = false; + this.map = null; + this.alphaMap = null; + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.fog = false; + this.setValues(parameters); + } + + MeshDepthMaterial.prototype = Object.create(Material.prototype); + MeshDepthMaterial.prototype.constructor = MeshDepthMaterial; + MeshDepthMaterial.prototype.isMeshDepthMaterial = true; + + MeshDepthMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.depthPacking = source.depthPacking; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.map = source.map; + this.alphaMap = source.alphaMap; + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; return this; + }; - }, - - copy: function ( frustum ) { + /** + * parameters = { + * + * referencePosition: , + * nearDistance: , + * farDistance: , + * + * skinning: , + * morphTargets: , + * + * map: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: + * + * } + */ - var planes = this.planes; + function MeshDistanceMaterial(parameters) { + Material.call(this); + this.type = 'MeshDistanceMaterial'; + this.referencePosition = new Vector3(); + this.nearDistance = 1; + this.farDistance = 1000; + this.skinning = false; + this.morphTargets = false; + this.map = null; + this.alphaMap = null; + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + this.fog = false; + this.setValues(parameters); + } + + MeshDistanceMaterial.prototype = Object.create(Material.prototype); + MeshDistanceMaterial.prototype.constructor = MeshDistanceMaterial; + MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true; + + MeshDistanceMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.referencePosition.copy(source.referencePosition); + this.nearDistance = source.nearDistance; + this.farDistance = source.farDistance; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.map = source.map; + this.alphaMap = source.alphaMap; + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + return this; + }; - for( var i = 0; i < 6; i ++ ) { + var vsm_frag = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include \nvoid main() {\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n\tfor ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n\t\t#ifdef HORIZONAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean * HALF_SAMPLE_RATE;\n\tsquared_mean = squared_mean * HALF_SAMPLE_RATE;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}"; - planes[i].copy( frustum.planes[i] ); + var vsm_vert = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; - } + function WebGLShadowMap(_renderer, _objects, maxTextureSize) { + var _frustum = new Frustum(); - return this; + var _shadowMapSize = new Vector2(), + _viewportSize = new Vector2(), + _viewport = new Vector4(), + _depthMaterials = [], + _distanceMaterials = [], + _materialCache = {}; - }, + var shadowSide = { + 0: BackSide, + 1: FrontSide, + 2: DoubleSide + }; + var shadowMaterialVertical = new ShaderMaterial({ + defines: { + SAMPLE_RATE: 2.0 / 8.0, + HALF_SAMPLE_RATE: 1.0 / 8.0 + }, + uniforms: { + shadow_pass: { + value: null + }, + resolution: { + value: new Vector2() + }, + radius: { + value: 4.0 + } + }, + vertexShader: vsm_vert, + fragmentShader: vsm_frag + }); + var shadowMaterialHorizonal = shadowMaterialVertical.clone(); + shadowMaterialHorizonal.defines.HORIZONAL_PASS = 1; + var fullScreenTri = new BufferGeometry(); + fullScreenTri.setAttribute("position", new BufferAttribute(new Float32Array([-1, -1, 0.5, 3, -1, 0.5, -1, 3, 0.5]), 3)); + var fullScreenMesh = new Mesh(fullScreenTri, shadowMaterialVertical); + var scope = this; + this.enabled = false; + this.autoUpdate = true; + this.needsUpdate = false; + this.type = PCFShadowMap; - setFromMatrix: function ( m ) { + this.render = function (lights, scene, camera) { + if (scope.enabled === false) return; + if (scope.autoUpdate === false && scope.needsUpdate === false) return; + if (lights.length === 0) return; - var planes = this.planes; - var me = m.elements; - var me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3]; - var me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7]; - var me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11]; - var me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15]; + var currentRenderTarget = _renderer.getRenderTarget(); - planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize(); - planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize(); - planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize(); - planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize(); - planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize(); - planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize(); + var activeCubeFace = _renderer.getActiveCubeFace(); - return this; + var activeMipmapLevel = _renderer.getActiveMipmapLevel(); - }, + var _state = _renderer.state; // Set GL state for depth map. - intersectsObject: function () { + _state.setBlending(NoBlending); - var sphere = new THREE.Sphere(); + _state.buffers.color.setClear(1, 1, 1, 1); - return function ( object ) { + _state.buffers.depth.setTest(true); - var geometry = object.geometry; + _state.setScissorTest(false); // render depth map - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( object.matrixWorld ); + for (var i = 0, il = lights.length; i < il; i++) { + var light = lights[i]; + var shadow = light.shadow; - return this.intersectsSphere( sphere ); + if (shadow === undefined) { + console.warn('THREE.WebGLShadowMap:', light, 'has no shadow.'); + continue; + } - }; + if (shadow.autoUpdate === false && shadow.needsUpdate === false) continue; - }(), + _shadowMapSize.copy(shadow.mapSize); - intersectsSphere: function ( sphere ) { + var shadowFrameExtents = shadow.getFrameExtents(); - var planes = this.planes; - var center = sphere.center; - var negRadius = -sphere.radius; + _shadowMapSize.multiply(shadowFrameExtents); - for ( var i = 0; i < 6; i ++ ) { + _viewportSize.copy(shadow.mapSize); - var distance = planes[ i ].distanceToPoint( center ); + if (_shadowMapSize.x > maxTextureSize || _shadowMapSize.y > maxTextureSize) { + if (_shadowMapSize.x > maxTextureSize) { + _viewportSize.x = Math.floor(maxTextureSize / shadowFrameExtents.x); + _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x; + shadow.mapSize.x = _viewportSize.x; + } - if ( distance < negRadius ) { + if (_shadowMapSize.y > maxTextureSize) { + _viewportSize.y = Math.floor(maxTextureSize / shadowFrameExtents.y); + _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; + shadow.mapSize.y = _viewportSize.y; + } + } - return false; + if (shadow.map === null && !shadow.isPointLightShadow && this.type === VSMShadowMap) { + var pars = { + minFilter: LinearFilter, + magFilter: LinearFilter, + format: RGBAFormat + }; + shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars); + shadow.map.texture.name = light.name + ".shadowMap"; + shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars); + shadow.camera.updateProjectionMatrix(); + } - } + if (shadow.map === null) { + var _pars = { + minFilter: NearestFilter, + magFilter: NearestFilter, + format: RGBAFormat + }; + shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, _pars); + shadow.map.texture.name = light.name + ".shadowMap"; + shadow.camera.updateProjectionMatrix(); + } - } + _renderer.setRenderTarget(shadow.map); - return true; + _renderer.clear(); - }, + var viewportCount = shadow.getViewportCount(); - intersectsBox : function() { + for (var vp = 0; vp < viewportCount; vp++) { + var viewport = shadow.getViewport(vp); - var p1 = new THREE.Vector3(), - p2 = new THREE.Vector3(); + _viewport.set(_viewportSize.x * viewport.x, _viewportSize.y * viewport.y, _viewportSize.x * viewport.z, _viewportSize.y * viewport.w); - return function( box ) { + _state.viewport(_viewport); - var planes = this.planes; - - for ( var i = 0; i < 6 ; i ++ ) { - - var plane = planes[i]; - - p1.x = plane.normal.x > 0 ? box.min.x : box.max.x; - p2.x = plane.normal.x > 0 ? box.max.x : box.min.x; - p1.y = plane.normal.y > 0 ? box.min.y : box.max.y; - p2.y = plane.normal.y > 0 ? box.max.y : box.min.y; - p1.z = plane.normal.z > 0 ? box.min.z : box.max.z; - p2.z = plane.normal.z > 0 ? box.max.z : box.min.z; - - var d1 = plane.distanceToPoint( p1 ); - var d2 = plane.distanceToPoint( p2 ); - - // if both outside plane, no intersection - - if ( d1 < 0 && d2 < 0 ) { - - return false; - + shadow.updateMatrices(light, vp); + _frustum = shadow.getFrustum(); + renderObject(scene, camera, shadow.camera, light, this.type); + } // do blur pass for VSM + + + if (!shadow.isPointLightShadow && this.type === VSMShadowMap) { + VSMPass(shadow, camera); } + + shadow.needsUpdate = false; } - return true; - }; + scope.needsUpdate = false; - }(), + _renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel); + }; + function VSMPass(shadow, camera) { + var geometry = _objects.update(fullScreenMesh); // vertical pass - containsPoint: function ( point ) { - var planes = this.planes; + shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; + shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; + shadowMaterialVertical.uniforms.radius.value = shadow.radius; - for ( var i = 0; i < 6; i ++ ) { + _renderer.setRenderTarget(shadow.mapPass); - if ( planes[ i ].distanceToPoint( point ) < 0 ) { + _renderer.clear(); - return false; + _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); // horizonal pass - } - } + shadowMaterialHorizonal.uniforms.shadow_pass.value = shadow.mapPass.texture; + shadowMaterialHorizonal.uniforms.resolution.value = shadow.mapSize; + shadowMaterialHorizonal.uniforms.radius.value = shadow.radius; - return true; + _renderer.setRenderTarget(shadow.map); - }, + _renderer.clear(); - clone: function () { + _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialHorizonal, fullScreenMesh, null); + } - return new THREE.Frustum().copy( this ); + function getDepthMaterialVariant(useMorphing, useSkinning, useInstancing) { + var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2; + var material = _depthMaterials[index]; - } + if (material === undefined) { + material = new MeshDepthMaterial({ + depthPacking: RGBADepthPacking, + morphTargets: useMorphing, + skinning: useSkinning + }); + _depthMaterials[index] = material; + } -}; + return material; + } -/** - * @author bhouston / http://exocortex.com - */ + function getDistanceMaterialVariant(useMorphing, useSkinning, useInstancing) { + var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2; + var material = _distanceMaterials[index]; -THREE.Plane = function ( normal, constant ) { + if (material === undefined) { + material = new MeshDistanceMaterial({ + morphTargets: useMorphing, + skinning: useSkinning + }); + _distanceMaterials[index] = material; + } - this.normal = ( normal !== undefined ) ? normal : new THREE.Vector3( 1, 0, 0 ); - this.constant = ( constant !== undefined ) ? constant : 0; + return material; + } -}; + function getDepthMaterial(object, geometry, material, light, shadowCameraNear, shadowCameraFar, type) { + var result = null; + var getMaterialVariant = getDepthMaterialVariant; + var customMaterial = object.customDepthMaterial; -THREE.Plane.prototype = { + if (light.isPointLight === true) { + getMaterialVariant = getDistanceMaterialVariant; + customMaterial = object.customDistanceMaterial; + } - constructor: THREE.Plane, + if (customMaterial === undefined) { + var useMorphing = false; - set: function ( normal, constant ) { + if (material.morphTargets === true) { + useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0; + } - this.normal.copy( normal ); - this.constant = constant; + var useSkinning = false; - return this; + if (object.isSkinnedMesh === true) { + if (material.skinning === true) { + useSkinning = true; + } else { + console.warn('THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object); + } + } - }, + var useInstancing = object.isInstancedMesh === true; + result = getMaterialVariant(useMorphing, useSkinning, useInstancing); + } else { + result = customMaterial; + } - setComponents: function ( x, y, z, w ) { + if (_renderer.localClippingEnabled && material.clipShadows === true && material.clippingPlanes.length !== 0) { + // in this case we need a unique material instance reflecting the + // appropriate state + var keyA = result.uuid, + keyB = material.uuid; + var materialsForVariant = _materialCache[keyA]; - this.normal.set( x, y, z ); - this.constant = w; + if (materialsForVariant === undefined) { + materialsForVariant = {}; + _materialCache[keyA] = materialsForVariant; + } - return this; + var cachedMaterial = materialsForVariant[keyB]; - }, + if (cachedMaterial === undefined) { + cachedMaterial = result.clone(); + materialsForVariant[keyB] = cachedMaterial; + } - setFromNormalAndCoplanarPoint: function ( normal, point ) { + result = cachedMaterial; + } - this.normal.copy( normal ); - this.constant = - point.dot( this.normal ); // must be this.normal, not normal, as this.normal is normalized + result.visible = material.visible; + result.wireframe = material.wireframe; - return this; + if (type === VSMShadowMap) { + result.side = material.shadowSide !== null ? material.shadowSide : material.side; + } else { + result.side = material.shadowSide !== null ? material.shadowSide : shadowSide[material.side]; + } - }, + result.clipShadows = material.clipShadows; + result.clippingPlanes = material.clippingPlanes; + result.clipIntersection = material.clipIntersection; + result.wireframeLinewidth = material.wireframeLinewidth; + result.linewidth = material.linewidth; - setFromCoplanarPoints: function() { + if (light.isPointLight === true && result.isMeshDistanceMaterial === true) { + result.referencePosition.setFromMatrixPosition(light.matrixWorld); + result.nearDistance = shadowCameraNear; + result.farDistance = shadowCameraFar; + } - var v1 = new THREE.Vector3(); - var v2 = new THREE.Vector3(); + return result; + } - return function ( a, b, c ) { + function renderObject(object, camera, shadowCamera, light, type) { + if (object.visible === false) return; + var visible = object.layers.test(camera.layers); - var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize(); + if (visible && (object.isMesh || object.isLine || object.isPoints)) { + if ((object.castShadow || object.receiveShadow && type === VSMShadowMap) && (!object.frustumCulled || _frustum.intersectsObject(object))) { + object.modelViewMatrix.multiplyMatrices(shadowCamera.matrixWorldInverse, object.matrixWorld); - // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? + var geometry = _objects.update(object); - this.setFromNormalAndCoplanarPoint( normal, a ); + var material = object.material; - return this; + if (Array.isArray(material)) { + var groups = geometry.groups; - }; + for (var k = 0, kl = groups.length; k < kl; k++) { + var group = groups[k]; + var groupMaterial = material[group.materialIndex]; - }(), + if (groupMaterial && groupMaterial.visible) { + var depthMaterial = getDepthMaterial(object, geometry, groupMaterial, light, shadowCamera.near, shadowCamera.far, type); + _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group); + } + } + } else if (material.visible) { + var _depthMaterial = getDepthMaterial(object, geometry, material, light, shadowCamera.near, shadowCamera.far, type); - copy: function ( plane ) { + _renderer.renderBufferDirect(shadowCamera, null, geometry, _depthMaterial, object, null); + } + } + } - this.normal.copy( plane.normal ); - this.constant = plane.constant; + var children = object.children; - return this; + for (var i = 0, l = children.length; i < l; i++) { + renderObject(children[i], camera, shadowCamera, light, type); + } + } + } - }, + function WebGLState(gl, extensions, capabilities) { + var _equationToGL, _factorToGL; - normalize: function () { + var isWebGL2 = capabilities.isWebGL2; - // Note: will lead to a divide by zero if the plane is invalid. + function ColorBuffer() { + var locked = false; + var color = new Vector4(); + var currentColorMask = null; + var currentColorClear = new Vector4(0, 0, 0, 0); + return { + setMask: function setMask(colorMask) { + if (currentColorMask !== colorMask && !locked) { + gl.colorMask(colorMask, colorMask, colorMask, colorMask); + currentColorMask = colorMask; + } + }, + setLocked: function setLocked(lock) { + locked = lock; + }, + setClear: function setClear(r, g, b, a, premultipliedAlpha) { + if (premultipliedAlpha === true) { + r *= a; + g *= a; + b *= a; + } - var inverseNormalLength = 1.0 / this.normal.length(); - this.normal.multiplyScalar( inverseNormalLength ); - this.constant *= inverseNormalLength; + color.set(r, g, b, a); - return this; + if (currentColorClear.equals(color) === false) { + gl.clearColor(r, g, b, a); + currentColorClear.copy(color); + } + }, + reset: function reset() { + locked = false; + currentColorMask = null; + currentColorClear.set(-1, 0, 0, 0); // set to invalid state + } + }; + } - }, + function DepthBuffer() { + var locked = false; + var currentDepthMask = null; + var currentDepthFunc = null; + var currentDepthClear = null; + return { + setTest: function setTest(depthTest) { + if (depthTest) { + enable(2929); + } else { + disable(2929); + } + }, + setMask: function setMask(depthMask) { + if (currentDepthMask !== depthMask && !locked) { + gl.depthMask(depthMask); + currentDepthMask = depthMask; + } + }, + setFunc: function setFunc(depthFunc) { + if (currentDepthFunc !== depthFunc) { + if (depthFunc) { + switch (depthFunc) { + case NeverDepth: + gl.depthFunc(512); + break; + + case AlwaysDepth: + gl.depthFunc(519); + break; + + case LessDepth: + gl.depthFunc(513); + break; + + case LessEqualDepth: + gl.depthFunc(515); + break; + + case EqualDepth: + gl.depthFunc(514); + break; + + case GreaterEqualDepth: + gl.depthFunc(518); + break; + + case GreaterDepth: + gl.depthFunc(516); + break; + + case NotEqualDepth: + gl.depthFunc(517); + break; + + default: + gl.depthFunc(515); + } + } else { + gl.depthFunc(515); + } - negate: function () { + currentDepthFunc = depthFunc; + } + }, + setLocked: function setLocked(lock) { + locked = lock; + }, + setClear: function setClear(depth) { + if (currentDepthClear !== depth) { + gl.clearDepth(depth); + currentDepthClear = depth; + } + }, + reset: function reset() { + locked = false; + currentDepthMask = null; + currentDepthFunc = null; + currentDepthClear = null; + } + }; + } - this.constant *= -1; - this.normal.negate(); + function StencilBuffer() { + var locked = false; + var currentStencilMask = null; + var currentStencilFunc = null; + var currentStencilRef = null; + var currentStencilFuncMask = null; + var currentStencilFail = null; + var currentStencilZFail = null; + var currentStencilZPass = null; + var currentStencilClear = null; + return { + setTest: function setTest(stencilTest) { + if (!locked) { + if (stencilTest) { + enable(2960); + } else { + disable(2960); + } + } + }, + setMask: function setMask(stencilMask) { + if (currentStencilMask !== stencilMask && !locked) { + gl.stencilMask(stencilMask); + currentStencilMask = stencilMask; + } + }, + setFunc: function setFunc(stencilFunc, stencilRef, stencilMask) { + if (currentStencilFunc !== stencilFunc || currentStencilRef !== stencilRef || currentStencilFuncMask !== stencilMask) { + gl.stencilFunc(stencilFunc, stencilRef, stencilMask); + currentStencilFunc = stencilFunc; + currentStencilRef = stencilRef; + currentStencilFuncMask = stencilMask; + } + }, + setOp: function setOp(stencilFail, stencilZFail, stencilZPass) { + if (currentStencilFail !== stencilFail || currentStencilZFail !== stencilZFail || currentStencilZPass !== stencilZPass) { + gl.stencilOp(stencilFail, stencilZFail, stencilZPass); + currentStencilFail = stencilFail; + currentStencilZFail = stencilZFail; + currentStencilZPass = stencilZPass; + } + }, + setLocked: function setLocked(lock) { + locked = lock; + }, + setClear: function setClear(stencil) { + if (currentStencilClear !== stencil) { + gl.clearStencil(stencil); + currentStencilClear = stencil; + } + }, + reset: function reset() { + locked = false; + currentStencilMask = null; + currentStencilFunc = null; + currentStencilRef = null; + currentStencilFuncMask = null; + currentStencilFail = null; + currentStencilZFail = null; + currentStencilZPass = null; + currentStencilClear = null; + } + }; + } // + + + var colorBuffer = new ColorBuffer(); + var depthBuffer = new DepthBuffer(); + var stencilBuffer = new StencilBuffer(); + var enabledCapabilities = {}; + var currentProgram = null; + var currentBlendingEnabled = null; + var currentBlending = null; + var currentBlendEquation = null; + var currentBlendSrc = null; + var currentBlendDst = null; + var currentBlendEquationAlpha = null; + var currentBlendSrcAlpha = null; + var currentBlendDstAlpha = null; + var currentPremultipledAlpha = false; + var currentFlipSided = null; + var currentCullFace = null; + var currentLineWidth = null; + var currentPolygonOffsetFactor = null; + var currentPolygonOffsetUnits = null; + var maxTextures = gl.getParameter(35661); + var lineWidthAvailable = false; + var version = 0; + var glVersion = gl.getParameter(7938); + + if (glVersion.indexOf('WebGL') !== -1) { + version = parseFloat(/^WebGL\ ([0-9])/.exec(glVersion)[1]); + lineWidthAvailable = version >= 1.0; + } else if (glVersion.indexOf('OpenGL ES') !== -1) { + version = parseFloat(/^OpenGL\ ES\ ([0-9])/.exec(glVersion)[1]); + lineWidthAvailable = version >= 2.0; + } + + var currentTextureSlot = null; + var currentBoundTextures = {}; + var currentScissor = new Vector4(); + var currentViewport = new Vector4(); + + function createTexture(type, target, count) { + var data = new Uint8Array(4); // 4 is required to match default unpack alignment of 4. + + var texture = gl.createTexture(); + gl.bindTexture(type, texture); + gl.texParameteri(type, 10241, 9728); + gl.texParameteri(type, 10240, 9728); + + for (var i = 0; i < count; i++) { + gl.texImage2D(target + i, 0, 6408, 1, 1, 0, 6408, 5121, data); + } + + return texture; + } + + var emptyTextures = {}; + emptyTextures[3553] = createTexture(3553, 3553, 1); + emptyTextures[34067] = createTexture(34067, 34069, 6); // init + + colorBuffer.setClear(0, 0, 0, 1); + depthBuffer.setClear(1); + stencilBuffer.setClear(0); + enable(2929); + depthBuffer.setFunc(LessEqualDepth); + setFlipSided(false); + setCullFace(CullFaceBack); + enable(2884); + setBlending(NoBlending); // + + function enable(id) { + if (enabledCapabilities[id] !== true) { + gl.enable(id); + enabledCapabilities[id] = true; + } + } + + function disable(id) { + if (enabledCapabilities[id] !== false) { + gl.disable(id); + enabledCapabilities[id] = false; + } + } + + function useProgram(program) { + if (currentProgram !== program) { + gl.useProgram(program); + currentProgram = program; + return true; + } - return this; + return false; + } - }, + var equationToGL = (_equationToGL = {}, _equationToGL[AddEquation] = 32774, _equationToGL[SubtractEquation] = 32778, _equationToGL[ReverseSubtractEquation] = 32779, _equationToGL); - distanceToPoint: function ( point ) { + if (isWebGL2) { + equationToGL[MinEquation] = 32775; + equationToGL[MaxEquation] = 32776; + } else { + var extension = extensions.get('EXT_blend_minmax'); - return this.normal.dot( point ) + this.constant; + if (extension !== null) { + equationToGL[MinEquation] = extension.MIN_EXT; + equationToGL[MaxEquation] = extension.MAX_EXT; + } + } - }, + var factorToGL = (_factorToGL = {}, _factorToGL[ZeroFactor] = 0, _factorToGL[OneFactor] = 1, _factorToGL[SrcColorFactor] = 768, _factorToGL[SrcAlphaFactor] = 770, _factorToGL[SrcAlphaSaturateFactor] = 776, _factorToGL[DstColorFactor] = 774, _factorToGL[DstAlphaFactor] = 772, _factorToGL[OneMinusSrcColorFactor] = 769, _factorToGL[OneMinusSrcAlphaFactor] = 771, _factorToGL[OneMinusDstColorFactor] = 775, _factorToGL[OneMinusDstAlphaFactor] = 773, _factorToGL); - distanceToSphere: function ( sphere ) { + function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha) { + if (blending === NoBlending) { + if (currentBlendingEnabled) { + disable(3042); + currentBlendingEnabled = false; + } - return this.distanceToPoint( sphere.center ) - sphere.radius; + return; + } - }, + if (!currentBlendingEnabled) { + enable(3042); + currentBlendingEnabled = true; + } - projectPoint: function ( point, optionalTarget ) { + if (blending !== CustomBlending) { + if (blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha) { + if (currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation) { + gl.blendEquation(32774); + currentBlendEquation = AddEquation; + currentBlendEquationAlpha = AddEquation; + } - return this.orthoPoint( point, optionalTarget ).sub( point ).negate(); + if (premultipliedAlpha) { + switch (blending) { + case NormalBlending: + gl.blendFuncSeparate(1, 771, 1, 771); + break; - }, + case AdditiveBlending: + gl.blendFunc(1, 1); + break; - orthoPoint: function ( point, optionalTarget ) { + case SubtractiveBlending: + gl.blendFuncSeparate(0, 0, 769, 771); + break; - var perpendicularMagnitude = this.distanceToPoint( point ); + case MultiplyBlending: + gl.blendFuncSeparate(0, 768, 0, 770); + break; - var result = optionalTarget || new THREE.Vector3(); - return result.copy( this.normal ).multiplyScalar( perpendicularMagnitude ); + default: + console.error('THREE.WebGLState: Invalid blending: ', blending); + break; + } + } else { + switch (blending) { + case NormalBlending: + gl.blendFuncSeparate(770, 771, 1, 771); + break; - }, + case AdditiveBlending: + gl.blendFunc(770, 1); + break; - isIntersectionLine: function ( line ) { + case SubtractiveBlending: + gl.blendFunc(0, 769); + break; - // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. + case MultiplyBlending: + gl.blendFunc(0, 768); + break; - var startSign = this.distanceToPoint( line.start ); - var endSign = this.distanceToPoint( line.end ); + default: + console.error('THREE.WebGLState: Invalid blending: ', blending); + break; + } + } - return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); + currentBlendSrc = null; + currentBlendDst = null; + currentBlendSrcAlpha = null; + currentBlendDstAlpha = null; + currentBlending = blending; + currentPremultipledAlpha = premultipliedAlpha; + } - }, + return; + } // custom blending - intersectLine: function() { - var v1 = new THREE.Vector3(); + blendEquationAlpha = blendEquationAlpha || blendEquation; + blendSrcAlpha = blendSrcAlpha || blendSrc; + blendDstAlpha = blendDstAlpha || blendDst; - return function ( line, optionalTarget ) { + if (blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha) { + gl.blendEquationSeparate(equationToGL[blendEquation], equationToGL[blendEquationAlpha]); + currentBlendEquation = blendEquation; + currentBlendEquationAlpha = blendEquationAlpha; + } - var result = optionalTarget || new THREE.Vector3(); + if (blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha) { + gl.blendFuncSeparate(factorToGL[blendSrc], factorToGL[blendDst], factorToGL[blendSrcAlpha], factorToGL[blendDstAlpha]); + currentBlendSrc = blendSrc; + currentBlendDst = blendDst; + currentBlendSrcAlpha = blendSrcAlpha; + currentBlendDstAlpha = blendDstAlpha; + } - var direction = line.delta( v1 ); + currentBlending = blending; + currentPremultipledAlpha = null; + } - var denominator = this.normal.dot( direction ); + function setMaterial(material, frontFaceCW) { + material.side === DoubleSide ? disable(2884) : enable(2884); + var flipSided = material.side === BackSide; + if (frontFaceCW) flipSided = !flipSided; + setFlipSided(flipSided); + material.blending === NormalBlending && material.transparent === false ? setBlending(NoBlending) : setBlending(material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha); + depthBuffer.setFunc(material.depthFunc); + depthBuffer.setTest(material.depthTest); + depthBuffer.setMask(material.depthWrite); + colorBuffer.setMask(material.colorWrite); + var stencilWrite = material.stencilWrite; + stencilBuffer.setTest(stencilWrite); - if ( denominator == 0 ) { + if (stencilWrite) { + stencilBuffer.setMask(material.stencilWriteMask); + stencilBuffer.setFunc(material.stencilFunc, material.stencilRef, material.stencilFuncMask); + stencilBuffer.setOp(material.stencilFail, material.stencilZFail, material.stencilZPass); + } - // line is coplanar, return origin - if( this.distanceToPoint( line.start ) == 0 ) { + setPolygonOffset(material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits); + } // - return result.copy( line.start ); + function setFlipSided(flipSided) { + if (currentFlipSided !== flipSided) { + if (flipSided) { + gl.frontFace(2304); + } else { + gl.frontFace(2305); } - // Unsure if this is the correct method to handle this case. - return undefined; - + currentFlipSided = flipSided; } + } - var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; + function setCullFace(cullFace) { + if (cullFace !== CullFaceNone) { + enable(2884); - if( t < 0 || t > 1 ) { + if (cullFace !== currentCullFace) { + if (cullFace === CullFaceBack) { + gl.cullFace(1029); + } else if (cullFace === CullFaceFront) { + gl.cullFace(1028); + } else { + gl.cullFace(1032); + } + } + } else { + disable(2884); + } - return undefined; + currentCullFace = cullFace; + } + function setLineWidth(width) { + if (width !== currentLineWidth) { + if (lineWidthAvailable) gl.lineWidth(width); + currentLineWidth = width; } + } - return result.copy( direction ).multiplyScalar( t ).add( line.start ); + function setPolygonOffset(polygonOffset, factor, units) { + if (polygonOffset) { + enable(32823); - }; + if (currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units) { + gl.polygonOffset(factor, units); + currentPolygonOffsetFactor = factor; + currentPolygonOffsetUnits = units; + } + } else { + disable(32823); + } + } + + function setScissorTest(scissorTest) { + if (scissorTest) { + enable(3089); + } else { + disable(3089); + } + } // texture - }(), + function activeTexture(webglSlot) { + if (webglSlot === undefined) webglSlot = 33984 + maxTextures - 1; - coplanarPoint: function ( optionalTarget ) { + if (currentTextureSlot !== webglSlot) { + gl.activeTexture(webglSlot); + currentTextureSlot = webglSlot; + } + } - var result = optionalTarget || new THREE.Vector3(); - return result.copy( this.normal ).multiplyScalar( - this.constant ); + function bindTexture(webglType, webglTexture) { + if (currentTextureSlot === null) { + activeTexture(); + } - }, + var boundTexture = currentBoundTextures[currentTextureSlot]; - applyMatrix4: function() { + if (boundTexture === undefined) { + boundTexture = { + type: undefined, + texture: undefined + }; + currentBoundTextures[currentTextureSlot] = boundTexture; + } - var v1 = new THREE.Vector3(); - var v2 = new THREE.Vector3(); - var m1 = new THREE.Matrix3(); + if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) { + gl.bindTexture(webglType, webglTexture || emptyTextures[webglType]); + boundTexture.type = webglType; + boundTexture.texture = webglTexture; + } + } - return function ( matrix, optionalNormalMatrix ) { + function unbindTexture() { + var boundTexture = currentBoundTextures[currentTextureSlot]; - // compute new normal based on theory here: - // http://www.songho.ca/opengl/gl_normaltransform.html - var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix ); - var newNormal = v1.copy( this.normal ).applyMatrix3( normalMatrix ); - - var newCoplanarPoint = this.coplanarPoint( v2 ); - newCoplanarPoint.applyMatrix4( matrix ); + if (boundTexture !== undefined && boundTexture.type !== undefined) { + gl.bindTexture(boundTexture.type, null); + boundTexture.type = undefined; + boundTexture.texture = undefined; + } + } - this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint ); + function compressedTexImage2D() { + try { + gl.compressedTexImage2D.apply(gl, arguments); + } catch (error) { + console.error('THREE.WebGLState:', error); + } + } - return this; + function texImage2D() { + try { + gl.texImage2D.apply(gl, arguments); + } catch (error) { + console.error('THREE.WebGLState:', error); + } + } - }; + function texImage3D() { + try { + gl.texImage3D.apply(gl, arguments); + } catch (error) { + console.error('THREE.WebGLState:', error); + } + } // - }(), - translate: function ( offset ) { + function scissor(scissor) { + if (currentScissor.equals(scissor) === false) { + gl.scissor(scissor.x, scissor.y, scissor.z, scissor.w); + currentScissor.copy(scissor); + } + } - this.constant = this.constant - offset.dot( this.normal ); + function viewport(viewport) { + if (currentViewport.equals(viewport) === false) { + gl.viewport(viewport.x, viewport.y, viewport.z, viewport.w); + currentViewport.copy(viewport); + } + } // - return this; - }, + function reset() { + enabledCapabilities = {}; + currentTextureSlot = null; + currentBoundTextures = {}; + currentProgram = null; + currentBlending = null; + currentFlipSided = null; + currentCullFace = null; + colorBuffer.reset(); + depthBuffer.reset(); + stencilBuffer.reset(); + } - equals: function ( plane ) { + return { + buffers: { + color: colorBuffer, + depth: depthBuffer, + stencil: stencilBuffer + }, + enable: enable, + disable: disable, + useProgram: useProgram, + setBlending: setBlending, + setMaterial: setMaterial, + setFlipSided: setFlipSided, + setCullFace: setCullFace, + setLineWidth: setLineWidth, + setPolygonOffset: setPolygonOffset, + setScissorTest: setScissorTest, + activeTexture: activeTexture, + bindTexture: bindTexture, + unbindTexture: unbindTexture, + compressedTexImage2D: compressedTexImage2D, + texImage2D: texImage2D, + texImage3D: texImage3D, + scissor: scissor, + viewport: viewport, + reset: reset + }; + } - return plane.normal.equals( this.normal ) && ( plane.constant == this.constant ); + function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info) { + var _wrappingToGL, _filterToGL; - }, + var isWebGL2 = capabilities.isWebGL2; + var maxTextures = capabilities.maxTextures; + var maxCubemapSize = capabilities.maxCubemapSize; + var maxTextureSize = capabilities.maxTextureSize; + var maxSamples = capabilities.maxSamples; - clone: function () { + var _videoTextures = new WeakMap(); - return new THREE.Plane().copy( this ); + var _canvas; // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas, + // also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")! + // Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d). - } -}; + var useOffscreenCanvas = false; -/** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - */ + try { + useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' && new OffscreenCanvas(1, 1).getContext("2d") !== null; + } catch (err) {// Ignore any errors + } -THREE.Math = { + function createCanvas(width, height) { + // Use OffscreenCanvas when available. Specially needed in web workers + return useOffscreenCanvas ? new OffscreenCanvas(width, height) : document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas'); + } - generateUUID: function () { + function resizeImage(image, needsPowerOfTwo, needsNewCanvas, maxSize) { + var scale = 1; // handle case if texture exceeds max size - // http://www.broofa.com/Tools/Math.uuid.htm - - var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); - var uuid = new Array(36); - var rnd = 0, r; + if (image.width > maxSize || image.height > maxSize) { + scale = maxSize / Math.max(image.width, image.height); + } // only perform resize if necessary - return function () { - for ( var i = 0; i < 36; i ++ ) { + if (scale < 1 || needsPowerOfTwo === true) { + // only perform resize for certain image types + if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) { + var floor = needsPowerOfTwo ? MathUtils.floorPowerOfTwo : Math.floor; + var width = floor(scale * image.width); + var height = floor(scale * image.height); + if (_canvas === undefined) _canvas = createCanvas(width, height); // cube textures can't reuse the same canvas - if ( i == 8 || i == 13 || i == 18 || i == 23 ) { - - uuid[ i ] = '-'; - - } else if ( i == 14 ) { - - uuid[ i ] = '4'; - + var canvas = needsNewCanvas ? createCanvas(width, height) : _canvas; + canvas.width = width; + canvas.height = height; + var context = canvas.getContext('2d'); + context.drawImage(image, 0, 0, width, height); + console.warn('THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').'); + return canvas; } else { - - if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0; - r = rnd & 0xf; - rnd = rnd >> 4; - uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; + if ('data' in image) { + console.warn('THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').'); + } + return image; } } - - return uuid.join(''); - }; + return image; + } + + function isPowerOfTwo(image) { + return MathUtils.isPowerOfTwo(image.width) && MathUtils.isPowerOfTwo(image.height); + } - }(), + function textureNeedsPowerOfTwo(texture) { + if (isWebGL2) return false; + return texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping || texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; + } - // Clamp value to range + function textureNeedsGenerateMipmaps(texture, supportsMips) { + return texture.generateMipmaps && supportsMips && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; + } - clamp: function ( x, a, b ) { + function generateMipmap(target, texture, width, height) { + _gl.generateMipmap(target); - return ( x < a ) ? a : ( ( x > b ) ? b : x ); + var textureProperties = properties.get(texture); // Note: Math.log( x ) * Math.LOG2E used instead of Math.log2( x ) which is not supported by IE11 - }, + textureProperties.__maxMipLevel = Math.log(Math.max(width, height)) * Math.LOG2E; + } - // Clamp value to range to range + if (glFormat === 6407) { + if (glType === 5126) internalFormat = 34837; + if (glType === 5131) internalFormat = 34843; + if (glType === 5121) internalFormat = 32849; + } - mapLinear: function ( x, a1, a2, b1, b2 ) { + if (glFormat === 6408) { + if (glType === 5126) internalFormat = 34836; + if (glType === 5131) internalFormat = 34842; + if (glType === 5121) internalFormat = 32856; + } - return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 ); + if (internalFormat === 33325 || internalFormat === 33326 || internalFormat === 34842 || internalFormat === 34836) { + extensions.get('EXT_color_buffer_float'); + } - }, + return internalFormat; + } // Fallback filters for non-power-of-2 textures - // http://en.wikipedia.org/wiki/Smoothstep - smoothstep: function ( x, min, max ) { + function filterFallback(f) { + if (f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter) { + return 9728; + } - if ( x <= min ) return 0; - if ( x >= max ) return 1; + return 9729; + } // - x = ( x - min )/( max - min ); - return x*x*(3 - 2*x); + function onTextureDispose(event) { + var texture = event.target; + texture.removeEventListener('dispose', onTextureDispose); + deallocateTexture(texture); - }, + if (texture.isVideoTexture) { + _videoTextures.delete(texture); + } - smootherstep: function ( x, min, max ) { + info.memory.textures--; + } - if ( x <= min ) return 0; - if ( x >= max ) return 1; + function onRenderTargetDispose(event) { + var renderTarget = event.target; + renderTarget.removeEventListener('dispose', onRenderTargetDispose); + deallocateRenderTarget(renderTarget); + info.memory.textures--; + } // - x = ( x - min )/( max - min ); - return x*x*x*(x*(x*6 - 15) + 10); + function deallocateTexture(texture) { + var textureProperties = properties.get(texture); + if (textureProperties.__webglInit === undefined) return; - }, + _gl.deleteTexture(textureProperties.__webglTexture); - // Random float from <0, 1> with 16 bits of randomness - // (standard Math.random() creates repetitive patterns when applied over larger space) + properties.remove(texture); + } - random16: function () { + function deallocateRenderTarget(renderTarget) { + var renderTargetProperties = properties.get(renderTarget); + var textureProperties = properties.get(renderTarget.texture); + if (!renderTarget) return; - return ( 65280 * Math.random() + 255 * Math.random() ) / 65535; + if (textureProperties.__webglTexture !== undefined) { + _gl.deleteTexture(textureProperties.__webglTexture); + } - }, + if (renderTarget.depthTexture) { + renderTarget.depthTexture.dispose(); + } - // Random integer from interval + if (renderTarget.isWebGLCubeRenderTarget) { + for (var i = 0; i < 6; i++) { + _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]); - randInt: function ( low, high ) { + if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer[i]); + } + } else { + _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer); - return low + Math.floor( Math.random() * ( high - low + 1 ) ); + if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer); + if (renderTargetProperties.__webglMultisampledFramebuffer) _gl.deleteFramebuffer(renderTargetProperties.__webglMultisampledFramebuffer); + if (renderTargetProperties.__webglColorRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglColorRenderbuffer); + if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer); + } - }, + properties.remove(renderTarget.texture); + properties.remove(renderTarget); + } // - // Random float from interval - randFloat: function ( low, high ) { + var textureUnits = 0; - return low + Math.random() * ( high - low ); + function resetTextureUnits() { + textureUnits = 0; + } - }, + function allocateTextureUnit() { + var textureUnit = textureUnits; - // Random float from <-range/2, range/2> interval + if (textureUnit >= maxTextures) { + console.warn('THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures); + } - randFloatSpread: function ( range ) { + textureUnits += 1; + return textureUnit; + } // - return range * ( 0.5 - Math.random() ); - }, + function setTexture2D(texture, slot) { + var textureProperties = properties.get(texture); + if (texture.isVideoTexture) updateVideoTexture(texture); - sign: function ( x ) { + if (texture.version > 0 && textureProperties.__version !== texture.version) { + var image = texture.image; - return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : 0; + if (image === undefined) { + console.warn('THREE.WebGLRenderer: Texture marked for update but image is undefined'); + } else if (image.complete === false) { + console.warn('THREE.WebGLRenderer: Texture marked for update but image is incomplete'); + } else { + uploadTexture(textureProperties, texture, slot); + return; + } + } - }, + state.activeTexture(33984 + slot); + state.bindTexture(3553, textureProperties.__webglTexture); + } - degToRad: function() { + function setTexture2DArray(texture, slot) { + var textureProperties = properties.get(texture); - var degreeToRadiansFactor = Math.PI / 180; + if (texture.version > 0 && textureProperties.__version !== texture.version) { + uploadTexture(textureProperties, texture, slot); + return; + } - return function ( degrees ) { + state.activeTexture(33984 + slot); + state.bindTexture(35866, textureProperties.__webglTexture); + } - return degrees * degreeToRadiansFactor; + function setTexture3D(texture, slot) { + var textureProperties = properties.get(texture); - }; + if (texture.version > 0 && textureProperties.__version !== texture.version) { + uploadTexture(textureProperties, texture, slot); + return; + } - }(), + state.activeTexture(33984 + slot); + state.bindTexture(32879, textureProperties.__webglTexture); + } - radToDeg: function() { + function setTextureCube(texture, slot) { + var textureProperties = properties.get(texture); - var radianToDegreesFactor = 180 / Math.PI; + if (texture.version > 0 && textureProperties.__version !== texture.version) { + uploadCubeTexture(textureProperties, texture, slot); + return; + } - return function ( radians ) { + state.activeTexture(33984 + slot); + state.bindTexture(34067, textureProperties.__webglTexture); + } - return radians * radianToDegreesFactor; + var wrappingToGL = (_wrappingToGL = {}, _wrappingToGL[RepeatWrapping] = 10497, _wrappingToGL[ClampToEdgeWrapping] = 33071, _wrappingToGL[MirroredRepeatWrapping] = 33648, _wrappingToGL); + var filterToGL = (_filterToGL = {}, _filterToGL[NearestFilter] = 9728, _filterToGL[NearestMipmapNearestFilter] = 9984, _filterToGL[NearestMipmapLinearFilter] = 9986, _filterToGL[LinearFilter] = 9729, _filterToGL[LinearMipmapNearestFilter] = 9985, _filterToGL[LinearMipmapLinearFilter] = 9987, _filterToGL); - }; + function setTextureParameters(textureType, texture, supportsMips) { + if (supportsMips) { + _gl.texParameteri(textureType, 10242, wrappingToGL[texture.wrapS]); - }(), + _gl.texParameteri(textureType, 10243, wrappingToGL[texture.wrapT]); - isPowerOfTwo: function ( value ) { + if (textureType === 32879 || textureType === 35866) { + _gl.texParameteri(textureType, 32882, wrappingToGL[texture.wrapR]); + } - return ( value & ( value - 1 ) ) === 0 && value !== 0; + _gl.texParameteri(textureType, 10240, filterToGL[texture.magFilter]); - } + _gl.texParameteri(textureType, 10241, filterToGL[texture.minFilter]); + } else { + _gl.texParameteri(textureType, 10242, 33071); -}; + _gl.texParameteri(textureType, 10243, 33071); -/** - * Spline from Tween.js, slightly optimized (and trashed) - * http://sole.github.com/tween.js/examples/05_spline.html - * - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + if (textureType === 32879 || textureType === 35866) { + _gl.texParameteri(textureType, 32882, 33071); + } -THREE.Spline = function ( points ) { + if (texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping) { + console.warn('THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.'); + } - this.points = points; + _gl.texParameteri(textureType, 10240, filterFallback(texture.magFilter)); - var c = [], v3 = { x: 0, y: 0, z: 0 }, - point, intPoint, weight, w2, w3, - pa, pb, pc, pd; + _gl.texParameteri(textureType, 10241, filterFallback(texture.minFilter)); - this.initFromArray = function( a ) { + if (texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) { + console.warn('THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.'); + } + } - this.points = []; + var extension = extensions.get('EXT_texture_filter_anisotropic'); - for ( var i = 0; i < a.length; i++ ) { + if (extension) { + if (texture.type === FloatType && extensions.get('OES_texture_float_linear') === null) return; + if (texture.type === HalfFloatType && (isWebGL2 || extensions.get('OES_texture_half_float_linear')) === null) return; - this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] }; + if (texture.anisotropy > 1 || properties.get(texture).__currentAnisotropy) { + _gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture.anisotropy, capabilities.getMaxAnisotropy())); + properties.get(texture).__currentAnisotropy = texture.anisotropy; + } + } } - }; + function initTexture(textureProperties, texture) { + if (textureProperties.__webglInit === undefined) { + textureProperties.__webglInit = true; + texture.addEventListener('dispose', onTextureDispose); + textureProperties.__webglTexture = _gl.createTexture(); + info.memory.textures++; + } + } - this.getPoint = function ( k ) { + function uploadTexture(textureProperties, texture, slot) { + var textureType = 3553; + if (texture.isDataTexture2DArray) textureType = 35866; + if (texture.isDataTexture3D) textureType = 32879; + initTexture(textureProperties, texture); + state.activeTexture(33984 + slot); + state.bindTexture(textureType, textureProperties.__webglTexture); - point = ( this.points.length - 1 ) * k; - intPoint = Math.floor( point ); - weight = point - intPoint; + _gl.pixelStorei(37440, texture.flipY); - c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1; - c[ 1 ] = intPoint; - c[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1; - c[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2; + _gl.pixelStorei(37441, texture.premultiplyAlpha); - pa = this.points[ c[ 0 ] ]; - pb = this.points[ c[ 1 ] ]; - pc = this.points[ c[ 2 ] ]; - pd = this.points[ c[ 3 ] ]; + _gl.pixelStorei(3317, texture.unpackAlignment); - w2 = weight * weight; - w3 = weight * w2; + var needsPowerOfTwo = textureNeedsPowerOfTwo(texture) && isPowerOfTwo(texture.image) === false; + var image = resizeImage(texture.image, needsPowerOfTwo, false, maxTextureSize); + var supportsMips = isPowerOfTwo(image) || isWebGL2, + glFormat = utils.convert(texture.format); + var glType = utils.convert(texture.type), + glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType); + setTextureParameters(textureType, texture, supportsMips); + var mipmap; + var mipmaps = texture.mipmaps; - v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 ); - v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 ); - v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 ); + if (texture.isDepthTexture) { + // populate depth texture with dummy data + glInternalFormat = 6402; - return v3; + if (isWebGL2) { + if (texture.type === FloatType) { + glInternalFormat = 36012; + } else if (texture.type === UnsignedIntType) { + glInternalFormat = 33190; + } else if (texture.type === UnsignedInt248Type) { + glInternalFormat = 35056; + } else { + glInternalFormat = 33189; // WebGL2 requires sized internalformat for glTexImage2D + } + } else { + if (texture.type === FloatType) { + console.error('WebGLRenderer: Floating point depth texture requires WebGL2.'); + } + } // validation checks for WebGL 1 - }; - this.getControlPointsArray = function () { + if (texture.format === DepthFormat && glInternalFormat === 6402) { + // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are + // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT + // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) + if (texture.type !== UnsignedShortType && texture.type !== UnsignedIntType) { + console.warn('THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.'); + texture.type = UnsignedShortType; + glType = utils.convert(texture.type); + } + } - var i, p, l = this.points.length, - coords = []; + if (texture.format === DepthStencilFormat && glInternalFormat === 6402) { + // Depth stencil textures need the DEPTH_STENCIL internal format + // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) + glInternalFormat = 34041; // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are + // DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL. + // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) + + if (texture.type !== UnsignedInt248Type) { + console.warn('THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.'); + texture.type = UnsignedInt248Type; + glType = utils.convert(texture.type); + } + } // - for ( i = 0; i < l; i ++ ) { - p = this.points[ i ]; - coords[ i ] = [ p.x, p.y, p.z ]; + state.texImage2D(3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null); + } else if (texture.isDataTexture) { + // use manually created mipmaps if available + // if there are no manual mipmaps + // set 0 level mipmap and then use GL to generate other mipmap levels + if (mipmaps.length > 0 && supportsMips) { + for (var i = 0, il = mipmaps.length; i < il; i++) { + mipmap = mipmaps[i]; + state.texImage2D(3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); + } - } + texture.generateMipmaps = false; + textureProperties.__maxMipLevel = mipmaps.length - 1; + } else { + state.texImage2D(3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data); + textureProperties.__maxMipLevel = 0; + } + } else if (texture.isCompressedTexture) { + for (var _i = 0, _il = mipmaps.length; _i < _il; _i++) { + mipmap = mipmaps[_i]; - return coords; + if (texture.format !== RGBAFormat && texture.format !== RGBFormat) { + if (glFormat !== null) { + state.compressedTexImage2D(3553, _i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); + } else { + console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()'); + } + } else { + state.texImage2D(3553, _i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); + } + } - }; + textureProperties.__maxMipLevel = mipmaps.length - 1; + } else if (texture.isDataTexture2DArray) { + state.texImage3D(35866, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); + textureProperties.__maxMipLevel = 0; + } else if (texture.isDataTexture3D) { + state.texImage3D(32879, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); + textureProperties.__maxMipLevel = 0; + } else { + // regular Texture (image, video, canvas) + // use manually created mipmaps if available + // if there are no manual mipmaps + // set 0 level mipmap and then use GL to generate other mipmap levels + if (mipmaps.length > 0 && supportsMips) { + for (var _i2 = 0, _il2 = mipmaps.length; _i2 < _il2; _i2++) { + mipmap = mipmaps[_i2]; + state.texImage2D(3553, _i2, glInternalFormat, glFormat, glType, mipmap); + } - // approximate length by summing linear segments + texture.generateMipmaps = false; + textureProperties.__maxMipLevel = mipmaps.length - 1; + } else { + state.texImage2D(3553, 0, glInternalFormat, glFormat, glType, image); + textureProperties.__maxMipLevel = 0; + } + } - this.getLength = function ( nSubDivisions ) { + if (textureNeedsGenerateMipmaps(texture, supportsMips)) { + generateMipmap(textureType, texture, image.width, image.height); + } - var i, index, nSamples, position, - point = 0, intPoint = 0, oldIntPoint = 0, - oldPosition = new THREE.Vector3(), - tmpVec = new THREE.Vector3(), - chunkLengths = [], - totalLength = 0; + textureProperties.__version = texture.version; + if (texture.onUpdate) texture.onUpdate(texture); + } - // first point has 0 length + function uploadCubeTexture(textureProperties, texture, slot) { + if (texture.image.length !== 6) return; + initTexture(textureProperties, texture); + state.activeTexture(33984 + slot); + state.bindTexture(34067, textureProperties.__webglTexture); - chunkLengths[ 0 ] = 0; + _gl.pixelStorei(37440, texture.flipY); - if ( !nSubDivisions ) nSubDivisions = 100; + var isCompressed = texture && (texture.isCompressedTexture || texture.image[0].isCompressedTexture); + var isDataTexture = texture.image[0] && texture.image[0].isDataTexture; + var cubeImage = []; - nSamples = this.points.length * nSubDivisions; + for (var i = 0; i < 6; i++) { + if (!isCompressed && !isDataTexture) { + cubeImage[i] = resizeImage(texture.image[i], false, true, maxCubemapSize); + } else { + cubeImage[i] = isDataTexture ? texture.image[i].image : texture.image[i]; + } + } - oldPosition.copy( this.points[ 0 ] ); + var image = cubeImage[0], + supportsMips = isPowerOfTwo(image) || isWebGL2, + glFormat = utils.convert(texture.format), + glType = utils.convert(texture.type), + glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType); + setTextureParameters(34067, texture, supportsMips); + var mipmaps; - for ( i = 1; i < nSamples; i ++ ) { + if (isCompressed) { + for (var _i3 = 0; _i3 < 6; _i3++) { + mipmaps = cubeImage[_i3].mipmaps; - index = i / nSamples; + for (var j = 0; j < mipmaps.length; j++) { + var mipmap = mipmaps[j]; - position = this.getPoint( index ); - tmpVec.copy( position ); + if (texture.format !== RGBAFormat && texture.format !== RGBFormat) { + if (glFormat !== null) { + state.compressedTexImage2D(34069 + _i3, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); + } else { + console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()'); + } + } else { + state.texImage2D(34069 + _i3, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); + } + } + } - totalLength += tmpVec.distanceTo( oldPosition ); + textureProperties.__maxMipLevel = mipmaps.length - 1; + } else { + mipmaps = texture.mipmaps; - oldPosition.copy( position ); + for (var _i4 = 0; _i4 < 6; _i4++) { + if (isDataTexture) { + state.texImage2D(34069 + _i4, 0, glInternalFormat, cubeImage[_i4].width, cubeImage[_i4].height, 0, glFormat, glType, cubeImage[_i4].data); - point = ( this.points.length - 1 ) * index; - intPoint = Math.floor( point ); + for (var _j = 0; _j < mipmaps.length; _j++) { + var _mipmap = mipmaps[_j]; + var mipmapImage = _mipmap.image[_i4].image; + state.texImage2D(34069 + _i4, _j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data); + } + } else { + state.texImage2D(34069 + _i4, 0, glInternalFormat, glFormat, glType, cubeImage[_i4]); - if ( intPoint != oldIntPoint ) { + for (var _j2 = 0; _j2 < mipmaps.length; _j2++) { + var _mipmap2 = mipmaps[_j2]; + state.texImage2D(34069 + _i4, _j2 + 1, glInternalFormat, glFormat, glType, _mipmap2.image[_i4]); + } + } + } - chunkLengths[ intPoint ] = totalLength; - oldIntPoint = intPoint; + textureProperties.__maxMipLevel = mipmaps.length; + } + if (textureNeedsGenerateMipmaps(texture, supportsMips)) { + // We assume images for cube map have the same size. + generateMipmap(34067, texture, image.width, image.height); } - } + textureProperties.__version = texture.version; + if (texture.onUpdate) texture.onUpdate(texture); + } // Render targets + // Setup storage for target texture and bind it to correct framebuffer - // last point ends with total length - chunkLengths[ chunkLengths.length ] = totalLength; + function setupFrameBufferTexture(framebuffer, renderTarget, attachment, textureTarget) { + var glFormat = utils.convert(renderTarget.texture.format); + var glType = utils.convert(renderTarget.texture.type); + var glInternalFormat = getInternalFormat(renderTarget.texture.internalFormat, glFormat, glType); + state.texImage2D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null); - return { chunks: chunkLengths, total: totalLength }; + _gl.bindFramebuffer(36160, framebuffer); - }; + _gl.framebufferTexture2D(36160, attachment, textureTarget, properties.get(renderTarget.texture).__webglTexture, 0); - this.reparametrizeByArcLength = function ( samplingCoef ) { + _gl.bindFramebuffer(36160, null); + } // Setup storage for internal depth/stencil buffers and bind to correct framebuffer - var i, j, - index, indexCurrent, indexNext, - linearDistance, realDistance, - sampling, position, - newpoints = [], - tmpVec = new THREE.Vector3(), - sl = this.getLength(); - newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() ); + function setupRenderBufferStorage(renderbuffer, renderTarget, isMultisample) { + _gl.bindRenderbuffer(36161, renderbuffer); - for ( i = 1; i < this.points.length; i++ ) { + if (renderTarget.depthBuffer && !renderTarget.stencilBuffer) { + var glInternalFormat = 33189; - //tmpVec.copy( this.points[ i - 1 ] ); - //linearDistance = tmpVec.distanceTo( this.points[ i ] ); + if (isMultisample) { + var depthTexture = renderTarget.depthTexture; - realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ]; + if (depthTexture && depthTexture.isDepthTexture) { + if (depthTexture.type === FloatType) { + glInternalFormat = 36012; + } else if (depthTexture.type === UnsignedIntType) { + glInternalFormat = 33190; + } + } - sampling = Math.ceil( samplingCoef * realDistance / sl.total ); + var samples = getRenderTargetSamples(renderTarget); - indexCurrent = ( i - 1 ) / ( this.points.length - 1 ); - indexNext = i / ( this.points.length - 1 ); + _gl.renderbufferStorageMultisample(36161, samples, glInternalFormat, renderTarget.width, renderTarget.height); + } else { + _gl.renderbufferStorage(36161, glInternalFormat, renderTarget.width, renderTarget.height); + } - for ( j = 1; j < sampling - 1; j++ ) { + _gl.framebufferRenderbuffer(36160, 36096, 36161, renderbuffer); + } else if (renderTarget.depthBuffer && renderTarget.stencilBuffer) { + if (isMultisample) { + var _samples = getRenderTargetSamples(renderTarget); - index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent ); + _gl.renderbufferStorageMultisample(36161, _samples, 35056, renderTarget.width, renderTarget.height); + } else { + _gl.renderbufferStorage(36161, 34041, renderTarget.width, renderTarget.height); + } - position = this.getPoint( index ); - newpoints.push( tmpVec.copy( position ).clone() ); + _gl.framebufferRenderbuffer(36160, 33306, 36161, renderbuffer); + } else { + var glFormat = utils.convert(renderTarget.texture.format); + var glType = utils.convert(renderTarget.texture.type); - } + var _glInternalFormat = getInternalFormat(renderTarget.texture.internalFormat, glFormat, glType); - newpoints.push( tmpVec.copy( this.points[ i ] ).clone() ); + if (isMultisample) { + var _samples2 = getRenderTargetSamples(renderTarget); - } + _gl.renderbufferStorageMultisample(36161, _samples2, _glInternalFormat, renderTarget.width, renderTarget.height); + } else { + _gl.renderbufferStorage(36161, _glInternalFormat, renderTarget.width, renderTarget.height); + } + } - this.points = newpoints; + _gl.bindRenderbuffer(36161, null); + } // Setup resources for a Depth Texture for a FBO (needs an extension) - }; - // Catmull-Rom + function setupDepthTexture(framebuffer, renderTarget) { + var isCube = renderTarget && renderTarget.isWebGLCubeRenderTarget; + if (isCube) throw new Error('Depth Texture with cube render targets is not supported'); - function interpolate( p0, p1, p2, p3, t, t2, t3 ) { + _gl.bindFramebuffer(36160, framebuffer); - var v0 = ( p2 - p0 ) * 0.5, - v1 = ( p3 - p1 ) * 0.5; + if (!(renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture)) { + throw new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture'); + } // upload an empty depth texture with framebuffer size - return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1; - }; + if (!properties.get(renderTarget.depthTexture).__webglTexture || renderTarget.depthTexture.image.width !== renderTarget.width || renderTarget.depthTexture.image.height !== renderTarget.height) { + renderTarget.depthTexture.image.width = renderTarget.width; + renderTarget.depthTexture.image.height = renderTarget.height; + renderTarget.depthTexture.needsUpdate = true; + } -}; + setTexture2D(renderTarget.depthTexture, 0); -/** - * @author bhouston / http://exocortex.com - * @author mrdoob / http://mrdoob.com/ - */ + var webglDepthTexture = properties.get(renderTarget.depthTexture).__webglTexture; -THREE.Triangle = function ( a, b, c ) { + if (renderTarget.depthTexture.format === DepthFormat) { + _gl.framebufferTexture2D(36160, 36096, 3553, webglDepthTexture, 0); + } else if (renderTarget.depthTexture.format === DepthStencilFormat) { + _gl.framebufferTexture2D(36160, 33306, 3553, webglDepthTexture, 0); + } else { + throw new Error('Unknown depthTexture format'); + } + } // Setup GL resources for a non-texture depth buffer - this.a = ( a !== undefined ) ? a : new THREE.Vector3(); - this.b = ( b !== undefined ) ? b : new THREE.Vector3(); - this.c = ( c !== undefined ) ? c : new THREE.Vector3(); -}; + function setupDepthRenderbuffer(renderTarget) { + var renderTargetProperties = properties.get(renderTarget); + var isCube = renderTarget.isWebGLCubeRenderTarget === true; -THREE.Triangle.normal = function() { + if (renderTarget.depthTexture) { + if (isCube) throw new Error('target.depthTexture not supported in Cube render targets'); + setupDepthTexture(renderTargetProperties.__webglFramebuffer, renderTarget); + } else { + if (isCube) { + renderTargetProperties.__webglDepthbuffer = []; - var v0 = new THREE.Vector3(); + for (var i = 0; i < 6; i++) { + _gl.bindFramebuffer(36160, renderTargetProperties.__webglFramebuffer[i]); - return function ( a, b, c, optionalTarget ) { + renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer(); + setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer[i], renderTarget, false); + } + } else { + _gl.bindFramebuffer(36160, renderTargetProperties.__webglFramebuffer); - var result = optionalTarget || new THREE.Vector3(); + renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); + setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false); + } + } - result.subVectors( c, b ); - v0.subVectors( a, b ); - result.cross( v0 ); + _gl.bindFramebuffer(36160, null); + } // Set up GL resources for the render target - var resultLengthSq = result.lengthSq(); - if( resultLengthSq > 0 ) { - return result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) ); + function setupRenderTarget(renderTarget) { + var renderTargetProperties = properties.get(renderTarget); + var textureProperties = properties.get(renderTarget.texture); + renderTarget.addEventListener('dispose', onRenderTargetDispose); + textureProperties.__webglTexture = _gl.createTexture(); + info.memory.textures++; + var isCube = renderTarget.isWebGLCubeRenderTarget === true; + var isMultisample = renderTarget.isWebGLMultisampleRenderTarget === true; + var supportsMips = isPowerOfTwo(renderTarget) || isWebGL2; // Handles WebGL2 RGBFormat fallback - #18858 - } + if (isWebGL2 && renderTarget.texture.format === RGBFormat && (renderTarget.texture.type === FloatType || renderTarget.texture.type === HalfFloatType)) { + renderTarget.texture.format = RGBAFormat; + console.warn('THREE.WebGLRenderer: Rendering to textures with RGB format is not supported. Using RGBA format instead.'); + } // Setup framebuffer - return result.set( 0, 0, 0 ); - }; + if (isCube) { + renderTargetProperties.__webglFramebuffer = []; -}(); + for (var i = 0; i < 6; i++) { + renderTargetProperties.__webglFramebuffer[i] = _gl.createFramebuffer(); + } + } else { + renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); -// static/instance method to calculate barycoordinates -// based on: http://www.blackpawn.com/texts/pointinpoly/default.html -THREE.Triangle.barycoordFromPoint = function() { + if (isMultisample) { + if (isWebGL2) { + renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); + renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer(); - var v0 = new THREE.Vector3(); - var v1 = new THREE.Vector3(); - var v2 = new THREE.Vector3(); + _gl.bindRenderbuffer(36161, renderTargetProperties.__webglColorRenderbuffer); - return function ( point, a, b, c, optionalTarget ) { + var glFormat = utils.convert(renderTarget.texture.format); + var glType = utils.convert(renderTarget.texture.type); + var glInternalFormat = getInternalFormat(renderTarget.texture.internalFormat, glFormat, glType); + var samples = getRenderTargetSamples(renderTarget); - v0.subVectors( c, a ); - v1.subVectors( b, a ); - v2.subVectors( point, a ); + _gl.renderbufferStorageMultisample(36161, samples, glInternalFormat, renderTarget.width, renderTarget.height); - var dot00 = v0.dot( v0 ); - var dot01 = v0.dot( v1 ); - var dot02 = v0.dot( v2 ); - var dot11 = v1.dot( v1 ); - var dot12 = v1.dot( v2 ); + _gl.bindFramebuffer(36160, renderTargetProperties.__webglMultisampledFramebuffer); - var denom = ( dot00 * dot11 - dot01 * dot01 ); + _gl.framebufferRenderbuffer(36160, 36064, 36161, renderTargetProperties.__webglColorRenderbuffer); - var result = optionalTarget || new THREE.Vector3(); + _gl.bindRenderbuffer(36161, null); - // colinear or singular triangle - if( denom == 0 ) { - // arbitrary location outside of triangle? - // not sure if this is the best idea, maybe should be returning undefined - return result.set( -2, -1, -1 ); - } + if (renderTarget.depthBuffer) { + renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer(); + setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true); + } - var invDenom = 1 / denom; - var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; - var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; + _gl.bindFramebuffer(36160, null); + } else { + console.warn('THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.'); + } + } + } // Setup color buffer - // barycoordinates must always sum to 1 - return result.set( 1 - u - v, v, u ); - }; + if (isCube) { + state.bindTexture(34067, textureProperties.__webglTexture); + setTextureParameters(34067, renderTarget.texture, supportsMips); -}(); + for (var _i5 = 0; _i5 < 6; _i5++) { + setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[_i5], renderTarget, 36064, 34069 + _i5); + } -THREE.Triangle.containsPoint = function() { + if (textureNeedsGenerateMipmaps(renderTarget.texture, supportsMips)) { + generateMipmap(34067, renderTarget.texture, renderTarget.width, renderTarget.height); + } - var v1 = new THREE.Vector3(); + state.bindTexture(34067, null); + } else { + state.bindTexture(3553, textureProperties.__webglTexture); + setTextureParameters(3553, renderTarget.texture, supportsMips); + setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, 36064, 3553); - return function ( point, a, b, c ) { + if (textureNeedsGenerateMipmaps(renderTarget.texture, supportsMips)) { + generateMipmap(3553, renderTarget.texture, renderTarget.width, renderTarget.height); + } - var result = THREE.Triangle.barycoordFromPoint( point, a, b, c, v1 ); + state.bindTexture(3553, null); + } // Setup depth and stencil buffers - return ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 ); - }; + if (renderTarget.depthBuffer) { + setupDepthRenderbuffer(renderTarget); + } + } -}(); + function updateRenderTargetMipmap(renderTarget) { + var texture = renderTarget.texture; + var supportsMips = isPowerOfTwo(renderTarget) || isWebGL2; -THREE.Triangle.prototype = { + if (textureNeedsGenerateMipmaps(texture, supportsMips)) { + var target = renderTarget.isWebGLCubeRenderTarget ? 34067 : 3553; - constructor: THREE.Triangle, + var webglTexture = properties.get(texture).__webglTexture; - set: function ( a, b, c ) { + state.bindTexture(target, webglTexture); + generateMipmap(target, texture, renderTarget.width, renderTarget.height); + state.bindTexture(target, null); + } + } - this.a.copy( a ); - this.b.copy( b ); - this.c.copy( c ); + function updateMultisampleRenderTarget(renderTarget) { + if (renderTarget.isWebGLMultisampleRenderTarget) { + if (isWebGL2) { + var renderTargetProperties = properties.get(renderTarget); - return this; + _gl.bindFramebuffer(36008, renderTargetProperties.__webglMultisampledFramebuffer); - }, + _gl.bindFramebuffer(36009, renderTargetProperties.__webglFramebuffer); - setFromPointsAndIndices: function ( points, i0, i1, i2 ) { + var width = renderTarget.width; + var height = renderTarget.height; + var mask = 16384; + if (renderTarget.depthBuffer) mask |= 256; + if (renderTarget.stencilBuffer) mask |= 1024; - this.a.copy( points[i0] ); - this.b.copy( points[i1] ); - this.c.copy( points[i2] ); + _gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, 9728); - return this; + _gl.bindFramebuffer(36160, renderTargetProperties.__webglMultisampledFramebuffer); // see #18905 - }, + } else { + console.warn('THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.'); + } + } + } - copy: function ( triangle ) { + function getRenderTargetSamples(renderTarget) { + return isWebGL2 && renderTarget.isWebGLMultisampleRenderTarget ? Math.min(maxSamples, renderTarget.samples) : 0; + } - this.a.copy( triangle.a ); - this.b.copy( triangle.b ); - this.c.copy( triangle.c ); + function updateVideoTexture(texture) { + var frame = info.render.frame; // Check the last frame we updated the VideoTexture - return this; + if (_videoTextures.get(texture) !== frame) { + _videoTextures.set(texture, frame); - }, + texture.update(); + } + } // backwards compatibility - area: function() { - var v0 = new THREE.Vector3(); - var v1 = new THREE.Vector3(); + var warnedTexture2D = false; + var warnedTextureCube = false; - return function () { + function safeSetTexture2D(texture, slot) { + if (texture && texture.isWebGLRenderTarget) { + if (warnedTexture2D === false) { + console.warn("THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead."); + warnedTexture2D = true; + } - v0.subVectors( this.c, this.b ); - v1.subVectors( this.a, this.b ); + texture = texture.texture; + } - return v0.cross( v1 ).length() * 0.5; + setTexture2D(texture, slot); + } - }; + function safeSetTextureCube(texture, slot) { + if (texture && texture.isWebGLCubeRenderTarget) { + if (warnedTextureCube === false) { + console.warn("THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead."); + warnedTextureCube = true; + } - }(), + texture = texture.texture; + } - midpoint: function ( optionalTarget ) { + setTextureCube(texture, slot); + } // - var result = optionalTarget || new THREE.Vector3(); - return result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); - }, + this.allocateTextureUnit = allocateTextureUnit; + this.resetTextureUnits = resetTextureUnits; + this.setTexture2D = setTexture2D; + this.setTexture2DArray = setTexture2DArray; + this.setTexture3D = setTexture3D; + this.setTextureCube = setTextureCube; + this.setupRenderTarget = setupRenderTarget; + this.updateRenderTargetMipmap = updateRenderTargetMipmap; + this.updateMultisampleRenderTarget = updateMultisampleRenderTarget; + this.safeSetTexture2D = safeSetTexture2D; + this.safeSetTextureCube = safeSetTextureCube; + } - normal: function ( optionalTarget ) { + function WebGLUtils(gl, extensions, capabilities) { + var isWebGL2 = capabilities.isWebGL2; - return THREE.Triangle.normal( this.a, this.b, this.c, optionalTarget ); + function convert(p) { + var extension; + if (p === UnsignedByteType) return 5121; + if (p === UnsignedShort4444Type) return 32819; + if (p === UnsignedShort5551Type) return 32820; + if (p === UnsignedShort565Type) return 33635; + if (p === ByteType) return 5120; + if (p === ShortType) return 5122; + if (p === UnsignedShortType) return 5123; + if (p === IntType) return 5124; + if (p === UnsignedIntType) return 5125; + if (p === FloatType) return 5126; - }, + if (p === HalfFloatType) { + if (isWebGL2) return 5131; + extension = extensions.get('OES_texture_half_float'); - plane: function ( optionalTarget ) { + if (extension !== null) { + return extension.HALF_FLOAT_OES; + } else { + return null; + } + } - var result = optionalTarget || new THREE.Plane(); + if (p === AlphaFormat) return 6406; + if (p === RGBFormat) return 6407; + if (p === RGBAFormat) return 6408; + if (p === LuminanceFormat) return 6409; + if (p === LuminanceAlphaFormat) return 6410; + if (p === DepthFormat) return 6402; + if (p === DepthStencilFormat) return 34041; + if (p === RedFormat) return 6403; // WebGL2 formats. + + if (p === RedIntegerFormat) return 36244; + if (p === RGFormat) return 33319; + if (p === RGIntegerFormat) return 33320; + if (p === RGBIntegerFormat) return 36248; + if (p === RGBAIntegerFormat) return 36249; + + if (p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) { + extension = extensions.get('WEBGL_compressed_texture_s3tc'); + + if (extension !== null) { + if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; + if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; + if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; + if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; + } else { + return null; + } + } - return result.setFromCoplanarPoints( this.a, this.b, this.c ); + if (p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format) { + extension = extensions.get('WEBGL_compressed_texture_pvrtc'); - }, + if (extension !== null) { + if (p === RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; + if (p === RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; + if (p === RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + if (p === RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + } else { + return null; + } + } - barycoordFromPoint: function ( point, optionalTarget ) { + if (p === RGB_ETC1_Format) { + extension = extensions.get('WEBGL_compressed_texture_etc1'); - return THREE.Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget ); + if (extension !== null) { + return extension.COMPRESSED_RGB_ETC1_WEBGL; + } else { + return null; + } + } - }, + if (p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format) { + extension = extensions.get('WEBGL_compressed_texture_etc'); - containsPoint: function ( point ) { + if (extension !== null) { + if (p === RGB_ETC2_Format) return extension.COMPRESSED_RGB8_ETC2; + if (p === RGBA_ETC2_EAC_Format) return extension.COMPRESSED_RGBA8_ETC2_EAC; + } + } - return THREE.Triangle.containsPoint( point, this.a, this.b, this.c ); + if (p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format || p === SRGB8_ALPHA8_ASTC_4x4_Format || p === SRGB8_ALPHA8_ASTC_5x4_Format || p === SRGB8_ALPHA8_ASTC_5x5_Format || p === SRGB8_ALPHA8_ASTC_6x5_Format || p === SRGB8_ALPHA8_ASTC_6x6_Format || p === SRGB8_ALPHA8_ASTC_8x5_Format || p === SRGB8_ALPHA8_ASTC_8x6_Format || p === SRGB8_ALPHA8_ASTC_8x8_Format || p === SRGB8_ALPHA8_ASTC_10x5_Format || p === SRGB8_ALPHA8_ASTC_10x6_Format || p === SRGB8_ALPHA8_ASTC_10x8_Format || p === SRGB8_ALPHA8_ASTC_10x10_Format || p === SRGB8_ALPHA8_ASTC_12x10_Format || p === SRGB8_ALPHA8_ASTC_12x12_Format) { + extension = extensions.get('WEBGL_compressed_texture_astc'); - }, + if (extension !== null) { + // TODO Complete? + return p; + } else { + return null; + } + } - equals: function ( triangle ) { + if (p === RGBA_BPTC_Format) { + extension = extensions.get('EXT_texture_compression_bptc'); - return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); + if (extension !== null) { + // TODO Complete? + return p; + } else { + return null; + } + } - }, + if (p === UnsignedInt248Type) { + if (isWebGL2) return 34042; + extension = extensions.get('WEBGL_depth_texture'); - clone: function () { + if (extension !== null) { + return extension.UNSIGNED_INT_24_8_WEBGL; + } else { + return null; + } + } + } - return new THREE.Triangle().copy( this ); + return { + convert: convert + }; + } + function ArrayCamera(array) { + PerspectiveCamera.call(this); + this.cameras = array || []; } -}; + ArrayCamera.prototype = Object.assign(Object.create(PerspectiveCamera.prototype), { + constructor: ArrayCamera, + isArrayCamera: true + }); -/** - * @author mrdoob / http://mrdoob.com/ - */ + function Group() { + Object3D.call(this); + this.type = 'Group'; + } -THREE.Vertex = function ( v ) { + Group.prototype = Object.assign(Object.create(Object3D.prototype), { + constructor: Group, + isGroup: true + }); - console.warn( 'THREE.Vertex has been DEPRECATED. Use THREE.Vector3 instead.') - return v; + function WebXRController() { + this._targetRay = null; + this._grip = null; + this._hand = null; + } -}; + Object.assign(WebXRController.prototype, { + constructor: WebXRController, + getHandSpace: function getHandSpace() { + if (this._hand === null) { + this._hand = new Group(); + this._hand.matrixAutoUpdate = false; + this._hand.visible = false; + this._hand.joints = []; + this._hand.inputState = { + pinching: false + }; -/** - * @author alteredq / http://alteredqualia.com/ - */ + if (window.XRHand) { + for (var i = 0; i <= window.XRHand.LITTLE_PHALANX_TIP; i++) { + // The transform of this joint will be updated with the joint pose on each frame + var joint = new Group(); + joint.matrixAutoUpdate = false; + joint.visible = false; -THREE.Clock = function ( autoStart ) { + this._hand.joints.push(joint); // ?? - this.autoStart = ( autoStart !== undefined ) ? autoStart : true; - this.startTime = 0; - this.oldTime = 0; - this.elapsedTime = 0; + this._hand.add(joint); + } + } + } - this.running = false; + return this._hand; + }, + getTargetRaySpace: function getTargetRaySpace() { + if (this._targetRay === null) { + this._targetRay = new Group(); + this._targetRay.matrixAutoUpdate = false; + this._targetRay.visible = false; + } -}; + return this._targetRay; + }, + getGripSpace: function getGripSpace() { + if (this._grip === null) { + this._grip = new Group(); + this._grip.matrixAutoUpdate = false; + this._grip.visible = false; + } -THREE.Clock.prototype = { + return this._grip; + }, + dispatchEvent: function dispatchEvent(event) { + if (this._targetRay !== null) { + this._targetRay.dispatchEvent(event); + } - constructor: THREE.Clock, + if (this._grip !== null) { + this._grip.dispatchEvent(event); + } - start: function () { + if (this._hand !== null) { + this._hand.dispatchEvent(event); + } - this.startTime = self.performance !== undefined && self.performance.now !== undefined - ? self.performance.now() - : Date.now(); + return this; + }, + disconnect: function disconnect(inputSource) { + this.dispatchEvent({ + type: 'disconnected', + data: inputSource + }); - this.oldTime = this.startTime; - this.running = true; - }, + if (this._targetRay !== null) { + this._targetRay.visible = false; + } - stop: function () { + if (this._grip !== null) { + this._grip.visible = false; + } - this.getElapsedTime(); - this.running = false; + if (this._hand !== null) { + this._hand.visible = false; + } - }, + return this; + }, + update: function update(inputSource, frame, referenceSpace) { + var inputPose = null; + var gripPose = null; + var handPose = null; + var targetRay = this._targetRay; + var grip = this._grip; + var hand = this._hand; + + if (inputSource) { + if (hand && inputSource.hand) { + handPose = true; + + for (var i = 0; i <= window.XRHand.LITTLE_PHALANX_TIP; i++) { + if (inputSource.hand[i]) { + // Update the joints groups with the XRJoint poses + var jointPose = frame.getJointPose(inputSource.hand[i], referenceSpace); + var joint = hand.joints[i]; + + if (jointPose !== null) { + joint.matrix.fromArray(jointPose.transform.matrix); + joint.matrix.decompose(joint.position, joint.rotation, joint.scale); + joint.jointRadius = jointPose.radius; + } - getElapsedTime: function () { + joint.visible = jointPose !== null; // Custom events + // Check pinch + + var indexTip = hand.joints[window.XRHand.INDEX_PHALANX_TIP]; + var thumbTip = hand.joints[window.XRHand.THUMB_PHALANX_TIP]; + var distance = indexTip.position.distanceTo(thumbTip.position); + var distanceToPinch = 0.02; + var threshold = 0.005; + + if (hand.inputState.pinching && distance > distanceToPinch + threshold) { + hand.inputState.pinching = false; + this.dispatchEvent({ + type: "pinchend", + handedness: inputSource.handedness, + target: this + }); + } else if (!hand.inputState.pinching && distance <= distanceToPinch - threshold) { + hand.inputState.pinching = true; + this.dispatchEvent({ + type: "pinchstart", + handedness: inputSource.handedness, + target: this + }); + } + } + } + } else { + if (targetRay !== null) { + inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace); - this.getDelta(); - return this.elapsedTime; + if (inputPose !== null) { + targetRay.matrix.fromArray(inputPose.transform.matrix); + targetRay.matrix.decompose(targetRay.position, targetRay.rotation, targetRay.scale); + } + } - }, + if (grip !== null && inputSource.gripSpace) { + gripPose = frame.getPose(inputSource.gripSpace, referenceSpace); - getDelta: function () { + if (gripPose !== null) { + grip.matrix.fromArray(gripPose.transform.matrix); + grip.matrix.decompose(grip.position, grip.rotation, grip.scale); + } + } + } + } - var diff = 0; + if (targetRay !== null) { + targetRay.visible = inputPose !== null; + } - if ( this.autoStart && ! this.running ) { + if (grip !== null) { + grip.visible = gripPose !== null; + } - this.start(); + if (hand !== null) { + hand.visible = handPose !== null; + } + return this; } + }); - if ( this.running ) { + function WebXRManager(renderer, gl) { + var scope = this; + var session = null; + var framebufferScaleFactor = 1.0; + var referenceSpace = null; + var referenceSpaceType = 'local-floor'; + var pose = null; + var controllers = []; + var inputSourcesMap = new Map(); // + + var cameraL = new PerspectiveCamera(); + cameraL.layers.enable(1); + cameraL.viewport = new Vector4(); + var cameraR = new PerspectiveCamera(); + cameraR.layers.enable(2); + cameraR.viewport = new Vector4(); + var cameras = [cameraL, cameraR]; + var cameraVR = new ArrayCamera(); + cameraVR.layers.enable(1); + cameraVR.layers.enable(2); + var _currentDepthNear = null; + var _currentDepthFar = null; // + + this.enabled = false; + this.isPresenting = false; + + this.getController = function (index) { + var controller = controllers[index]; + + if (controller === undefined) { + controller = new WebXRController(); + controllers[index] = controller; + } + + return controller.getTargetRaySpace(); + }; - var newTime = self.performance !== undefined && self.performance.now !== undefined - ? self.performance.now() - : Date.now(); + this.getControllerGrip = function (index) { + var controller = controllers[index]; - diff = 0.001 * ( newTime - this.oldTime ); - this.oldTime = newTime; + if (controller === undefined) { + controller = new WebXRController(); + controllers[index] = controller; + } - this.elapsedTime += diff; + return controller.getGripSpace(); + }; - } + this.getHand = function (index) { + var controller = controllers[index]; - return diff; + if (controller === undefined) { + controller = new WebXRController(); + controllers[index] = controller; + } - } + return controller.getHandSpace(); + }; // -}; -/** - * https://github.com/mrdoob/eventdispatcher.js/ - */ + function onSessionEvent(event) { + var controller = inputSourcesMap.get(event.inputSource); -THREE.EventDispatcher = function () {} + if (controller) { + controller.dispatchEvent({ + type: event.type, + data: event.inputSource + }); + } + } -THREE.EventDispatcher.prototype = { + function onSessionEnd() { + inputSourcesMap.forEach(function (controller, inputSource) { + controller.disconnect(inputSource); + }); + inputSourcesMap.clear(); // - constructor: THREE.EventDispatcher, + renderer.setFramebuffer(null); + renderer.setRenderTarget(renderer.getRenderTarget()); // Hack #15830 - apply: function ( object ) { + animation.stop(); + scope.isPresenting = false; + scope.dispatchEvent({ + type: 'sessionend' + }); + } - object.addEventListener = THREE.EventDispatcher.prototype.addEventListener; - object.hasEventListener = THREE.EventDispatcher.prototype.hasEventListener; - object.removeEventListener = THREE.EventDispatcher.prototype.removeEventListener; - object.dispatchEvent = THREE.EventDispatcher.prototype.dispatchEvent; + function onRequestReferenceSpace(value) { + referenceSpace = value; + animation.setContext(session); + animation.start(); + scope.isPresenting = true; + scope.dispatchEvent({ + type: 'sessionstart' + }); + } - }, + this.setFramebufferScaleFactor = function (value) { + framebufferScaleFactor = value; - addEventListener: function ( type, listener ) { + if (scope.isPresenting === true) { + console.warn('THREE.WebXRManager: Cannot change framebuffer scale while presenting.'); + } + }; - if ( this._listeners === undefined ) this._listeners = {}; + this.setReferenceSpaceType = function (value) { + referenceSpaceType = value; - var listeners = this._listeners; + if (scope.isPresenting === true) { + console.warn('THREE.WebXRManager: Cannot change reference space type while presenting.'); + } + }; - if ( listeners[ type ] === undefined ) { + this.getReferenceSpace = function () { + return referenceSpace; + }; - listeners[ type ] = []; + this.getSession = function () { + return session; + }; - } + this.setSession = function (value) { + session = value; + + if (session !== null) { + session.addEventListener('select', onSessionEvent); + session.addEventListener('selectstart', onSessionEvent); + session.addEventListener('selectend', onSessionEvent); + session.addEventListener('squeeze', onSessionEvent); + session.addEventListener('squeezestart', onSessionEvent); + session.addEventListener('squeezeend', onSessionEvent); + session.addEventListener('end', onSessionEnd); + var attributes = gl.getContextAttributes(); + + if (attributes.xrCompatible !== true) { + gl.makeXRCompatible(); + } - if ( listeners[ type ].indexOf( listener ) === - 1 ) { + var layerInit = { + antialias: attributes.antialias, + alpha: attributes.alpha, + depth: attributes.depth, + stencil: attributes.stencil, + framebufferScaleFactor: framebufferScaleFactor + }; // eslint-disable-next-line no-undef - listeners[ type ].push( listener ); + var baseLayer = new XRWebGLLayer(session, gl, layerInit); + session.updateRenderState({ + baseLayer: baseLayer + }); + session.requestReferenceSpace(referenceSpaceType).then(onRequestReferenceSpace); // - } + session.addEventListener('inputsourceschange', updateInputSources); + } + }; - }, + function updateInputSources(event) { + var inputSources = session.inputSources; // Assign inputSources to available controllers - hasEventListener: function ( type, listener ) { + for (var i = 0; i < controllers.length; i++) { + inputSourcesMap.set(inputSources[i], controllers[i]); + } // Notify disconnected - if ( this._listeners === undefined ) return false; - var listeners = this._listeners; + for (var _i = 0; _i < event.removed.length; _i++) { + var inputSource = event.removed[_i]; + var controller = inputSourcesMap.get(inputSource); - if ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) { + if (controller) { + controller.dispatchEvent({ + type: 'disconnected', + data: inputSource + }); + inputSourcesMap.delete(inputSource); + } + } // Notify connected - return true; - } + for (var _i2 = 0; _i2 < event.added.length; _i2++) { + var _inputSource = event.added[_i2]; - return false; + var _controller = inputSourcesMap.get(_inputSource); - }, + if (_controller) { + _controller.dispatchEvent({ + type: 'connected', + data: _inputSource + }); + } + } + } // + + + var cameraLPos = new Vector3(); + var cameraRPos = new Vector3(); + /** + * Assumes 2 cameras that are parallel and share an X-axis, and that + * the cameras' projection and world matrices have already been set. + * And that near and far planes are identical for both cameras. + * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765 + */ + + function setProjectionFromUnion(camera, cameraL, cameraR) { + cameraLPos.setFromMatrixPosition(cameraL.matrixWorld); + cameraRPos.setFromMatrixPosition(cameraR.matrixWorld); + var ipd = cameraLPos.distanceTo(cameraRPos); + var projL = cameraL.projectionMatrix.elements; + var projR = cameraR.projectionMatrix.elements; // VR systems will have identical far and near planes, and + // most likely identical top and bottom frustum extents. + // Use the left camera for these values. + + var near = projL[14] / (projL[10] - 1); + var far = projL[14] / (projL[10] + 1); + var topFov = (projL[9] + 1) / projL[5]; + var bottomFov = (projL[9] - 1) / projL[5]; + var leftFov = (projL[8] - 1) / projL[0]; + var rightFov = (projR[8] + 1) / projR[0]; + var left = near * leftFov; + var right = near * rightFov; // Calculate the new camera's position offset from the + // left camera. xOffset should be roughly half `ipd`. + + var zOffset = ipd / (-leftFov + rightFov); + var xOffset = zOffset * -leftFov; // TODO: Better way to apply this offset? + + cameraL.matrixWorld.decompose(camera.position, camera.quaternion, camera.scale); + camera.translateX(xOffset); + camera.translateZ(zOffset); + camera.matrixWorld.compose(camera.position, camera.quaternion, camera.scale); + camera.matrixWorldInverse.getInverse(camera.matrixWorld); // Find the union of the frustum values of the cameras and scale + // the values so that the near plane's position does not change in world space, + // although must now be relative to the new union camera. + + var near2 = near + zOffset; + var far2 = far + zOffset; + var left2 = left - xOffset; + var right2 = right + (ipd - xOffset); + var top2 = topFov * far / far2 * near2; + var bottom2 = bottomFov * far / far2 * near2; + camera.projectionMatrix.makePerspective(left2, right2, top2, bottom2, near2, far2); + } + + function updateCamera(camera, parent) { + if (parent === null) { + camera.matrixWorld.copy(camera.matrix); + } else { + camera.matrixWorld.multiplyMatrices(parent.matrixWorld, camera.matrix); + } - removeEventListener: function ( type, listener ) { + camera.matrixWorldInverse.getInverse(camera.matrixWorld); + } - if ( this._listeners === undefined ) return; + this.getCamera = function (camera) { + cameraVR.near = cameraR.near = cameraL.near = camera.near; + cameraVR.far = cameraR.far = cameraL.far = camera.far; - var listeners = this._listeners; - var listenerArray = listeners[ type ]; + if (_currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far) { + // Note that the new renderState won't apply until the next frame. See #18320 + session.updateRenderState({ + depthNear: cameraVR.near, + depthFar: cameraVR.far + }); + _currentDepthNear = cameraVR.near; + _currentDepthFar = cameraVR.far; + } - if ( listenerArray !== undefined ) { + var parent = camera.parent; + var cameras = cameraVR.cameras; + updateCamera(cameraVR, parent); - var index = listenerArray.indexOf( listener ); + for (var i = 0; i < cameras.length; i++) { + updateCamera(cameras[i], parent); + } // update camera and its children - if ( index !== - 1 ) { - listenerArray.splice( index, 1 ); + camera.matrixWorld.copy(cameraVR.matrixWorld); + var children = camera.children; - } + for (var _i3 = 0, l = children.length; _i3 < l; _i3++) { + children[_i3].updateMatrixWorld(true); + } // update projection matrix for proper view frustum culling - } - }, + if (cameras.length === 2) { + setProjectionFromUnion(cameraVR, cameraL, cameraR); + } else { + // assume single camera setup (AR) + cameraVR.projectionMatrix.copy(cameraL.projectionMatrix); + } - dispatchEvent: function ( event ) { - - if ( this._listeners === undefined ) return; + return cameraVR; + }; // Animation Loop - var listeners = this._listeners; - var listenerArray = listeners[ event.type ]; - if ( listenerArray !== undefined ) { + var onAnimationFrameCallback = null; - event.target = this; + function onAnimationFrame(time, frame) { + pose = frame.getViewerPose(referenceSpace); - var array = []; - var length = listenerArray.length; + if (pose !== null) { + var views = pose.views; + var baseLayer = session.renderState.baseLayer; + renderer.setFramebuffer(baseLayer.framebuffer); + var cameraVRNeedsUpdate = false; // check if it's necessary to rebuild cameraVR's camera list + + if (views.length !== cameraVR.cameras.length) { + cameraVR.cameras.length = 0; + cameraVRNeedsUpdate = true; + } - for ( var i = 0; i < length; i ++ ) { + for (var i = 0; i < views.length; i++) { + var view = views[i]; + var viewport = baseLayer.getViewport(view); + var camera = cameras[i]; + camera.matrix.fromArray(view.transform.matrix); + camera.projectionMatrix.fromArray(view.projectionMatrix); + camera.viewport.set(viewport.x, viewport.y, viewport.width, viewport.height); - array[ i ] = listenerArray[ i ]; + if (i === 0) { + cameraVR.matrix.copy(camera.matrix); + } - } + if (cameraVRNeedsUpdate === true) { + cameraVR.cameras.push(camera); + } + } + } // - for ( var i = 0; i < length; i ++ ) { - array[ i ].call( this, event ); + var inputSources = session.inputSources; + for (var _i4 = 0; _i4 < controllers.length; _i4++) { + var controller = controllers[_i4]; + var inputSource = inputSources[_i4]; + controller.update(inputSource, frame, referenceSpace); } + if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame); } - } - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - * @author bhouston / http://exocortex.com/ - * @author stephomi / http://stephaneginier.com/ - */ + var animation = new WebGLAnimation(); + animation.setAnimationLoop(onAnimationFrame); -( function ( THREE ) { + this.setAnimationLoop = function (callback) { + onAnimationFrameCallback = callback; + }; - THREE.Raycaster = function ( origin, direction, near, far ) { + this.dispose = function () {}; + } - this.ray = new THREE.Ray( origin, direction ); - // direction is assumed to be normalized (for accurate distance calculations) + Object.assign(WebXRManager.prototype, EventDispatcher.prototype); - this.near = near || 0; - this.far = far || Infinity; + function WebGLMaterials(properties) { + function refreshFogUniforms(uniforms, fog) { + uniforms.fogColor.value.copy(fog.color); - }; + if (fog.isFog) { + uniforms.fogNear.value = fog.near; + uniforms.fogFar.value = fog.far; + } else if (fog.isFogExp2) { + uniforms.fogDensity.value = fog.density; + } + } - var sphere = new THREE.Sphere(); - var localRay = new THREE.Ray(); - var facePlane = new THREE.Plane(); - var intersectPoint = new THREE.Vector3(); - var matrixPosition = new THREE.Vector3(); + function refreshMaterialUniforms(uniforms, material, pixelRatio, height) { + if (material.isMeshBasicMaterial) { + refreshUniformsCommon(uniforms, material); + } else if (material.isMeshLambertMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsLambert(uniforms, material); + } else if (material.isMeshToonMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsToon(uniforms, material); + } else if (material.isMeshPhongMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsPhong(uniforms, material); + } else if (material.isMeshStandardMaterial) { + refreshUniformsCommon(uniforms, material); - var inverseMatrix = new THREE.Matrix4(); + if (material.isMeshPhysicalMaterial) { + refreshUniformsPhysical(uniforms, material); + } else { + refreshUniformsStandard(uniforms, material); + } + } else if (material.isMeshMatcapMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsMatcap(uniforms, material); + } else if (material.isMeshDepthMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsDepth(uniforms, material); + } else if (material.isMeshDistanceMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsDistance(uniforms, material); + } else if (material.isMeshNormalMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsNormal(uniforms, material); + } else if (material.isLineBasicMaterial) { + refreshUniformsLine(uniforms, material); + + if (material.isLineDashedMaterial) { + refreshUniformsDash(uniforms, material); + } + } else if (material.isPointsMaterial) { + refreshUniformsPoints(uniforms, material, pixelRatio, height); + } else if (material.isSpriteMaterial) { + refreshUniformsSprites(uniforms, material); + } else if (material.isShadowMaterial) { + uniforms.color.value.copy(material.color); + uniforms.opacity.value = material.opacity; + } else if (material.isShaderMaterial) { + material.uniformsNeedUpdate = false; // #15581 + } + } - var descSort = function ( a, b ) { + function refreshUniformsCommon(uniforms, material) { + uniforms.opacity.value = material.opacity; - return a.distance - b.distance; + if (material.color) { + uniforms.diffuse.value.copy(material.color); + } - }; + if (material.emissive) { + uniforms.emissive.value.copy(material.emissive).multiplyScalar(material.emissiveIntensity); + } - var vA = new THREE.Vector3(); - var vB = new THREE.Vector3(); - var vC = new THREE.Vector3(); + if (material.map) { + uniforms.map.value = material.map; + } - var intersectObject = function ( object, raycaster, intersects ) { + if (material.alphaMap) { + uniforms.alphaMap.value = material.alphaMap; + } - if ( object instanceof THREE.Sprite ) { + if (material.specularMap) { + uniforms.specularMap.value = material.specularMap; + } - matrixPosition.setFromMatrixPosition( object.matrixWorld ); - - var distance = raycaster.ray.distanceToPoint( matrixPosition ); + var envMap = properties.get(material).envMap; - if ( distance > object.scale.x ) { + if (envMap) { + uniforms.envMap.value = envMap; + uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap._needsFlipEnvMap ? -1 : 1; + uniforms.reflectivity.value = material.reflectivity; + uniforms.refractionRatio.value = material.refractionRatio; - return intersects; + var maxMipLevel = properties.get(envMap).__maxMipLevel; + if (maxMipLevel !== undefined) { + uniforms.maxMipLevel.value = maxMipLevel; + } } - intersects.push( { - - distance: distance, - point: object.position, - face: null, - object: object + if (material.lightMap) { + uniforms.lightMap.value = material.lightMap; + uniforms.lightMapIntensity.value = material.lightMapIntensity; + } + + if (material.aoMap) { + uniforms.aoMap.value = material.aoMap; + uniforms.aoMapIntensity.value = material.aoMapIntensity; + } // uv repeat and offset setting priorities + // 1. color map + // 2. specular map + // 3. displacementMap map + // 4. normal map + // 5. bump map + // 6. roughnessMap map + // 7. metalnessMap map + // 8. alphaMap map + // 9. emissiveMap map + // 10. clearcoat map + // 11. clearcoat normal map + // 12. clearcoat roughnessMap map + + + var uvScaleMap; + + if (material.map) { + uvScaleMap = material.map; + } else if (material.specularMap) { + uvScaleMap = material.specularMap; + } else if (material.displacementMap) { + uvScaleMap = material.displacementMap; + } else if (material.normalMap) { + uvScaleMap = material.normalMap; + } else if (material.bumpMap) { + uvScaleMap = material.bumpMap; + } else if (material.roughnessMap) { + uvScaleMap = material.roughnessMap; + } else if (material.metalnessMap) { + uvScaleMap = material.metalnessMap; + } else if (material.alphaMap) { + uvScaleMap = material.alphaMap; + } else if (material.emissiveMap) { + uvScaleMap = material.emissiveMap; + } else if (material.clearcoatMap) { + uvScaleMap = material.clearcoatMap; + } else if (material.clearcoatNormalMap) { + uvScaleMap = material.clearcoatNormalMap; + } else if (material.clearcoatRoughnessMap) { + uvScaleMap = material.clearcoatRoughnessMap; + } + + if (uvScaleMap !== undefined) { + // backwards compatibility + if (uvScaleMap.isWebGLRenderTarget) { + uvScaleMap = uvScaleMap.texture; + } - } ); + if (uvScaleMap.matrixAutoUpdate === true) { + uvScaleMap.updateMatrix(); + } - } else if ( object instanceof THREE.LOD ) { + uniforms.uvTransform.value.copy(uvScaleMap.matrix); + } // uv repeat and offset setting priorities for uv2 + // 1. ao map + // 2. light map - matrixPosition.setFromMatrixPosition( object.matrixWorld ); - var distance = raycaster.ray.origin.distanceTo( matrixPosition ); - intersectObject( object.getObjectForDistance( distance ), raycaster, intersects ); + var uv2ScaleMap; - } else if ( object instanceof THREE.Mesh ) { + if (material.aoMap) { + uv2ScaleMap = material.aoMap; + } else if (material.lightMap) { + uv2ScaleMap = material.lightMap; + } - var geometry = object.geometry; + if (uv2ScaleMap !== undefined) { + // backwards compatibility + if (uv2ScaleMap.isWebGLRenderTarget) { + uv2ScaleMap = uv2ScaleMap.texture; + } - // Checking boundingSphere distance to ray + if (uv2ScaleMap.matrixAutoUpdate === true) { + uv2ScaleMap.updateMatrix(); + } - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + uniforms.uv2Transform.value.copy(uv2ScaleMap.matrix); + } + } - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( object.matrixWorld ); + function refreshUniformsLine(uniforms, material) { + uniforms.diffuse.value.copy(material.color); + uniforms.opacity.value = material.opacity; + } - if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) { + function refreshUniformsDash(uniforms, material) { + uniforms.dashSize.value = material.dashSize; + uniforms.totalSize.value = material.dashSize + material.gapSize; + uniforms.scale.value = material.scale; + } - return intersects; + function refreshUniformsPoints(uniforms, material, pixelRatio, height) { + uniforms.diffuse.value.copy(material.color); + uniforms.opacity.value = material.opacity; + uniforms.size.value = material.size * pixelRatio; + uniforms.scale.value = height * 0.5; + if (material.map) { + uniforms.map.value = material.map; } - // Check boundingBox before continuing - - inverseMatrix.getInverse( object.matrixWorld ); - localRay.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + if (material.alphaMap) { + uniforms.alphaMap.value = material.alphaMap; + } // uv repeat and offset setting priorities + // 1. color map + // 2. alpha map - if ( geometry.boundingBox !== null ) { - if ( localRay.isIntersectionBox( geometry.boundingBox ) === false ) { + var uvScaleMap; - return intersects; + if (material.map) { + uvScaleMap = material.map; + } else if (material.alphaMap) { + uvScaleMap = material.alphaMap; + } + if (uvScaleMap !== undefined) { + if (uvScaleMap.matrixAutoUpdate === true) { + uvScaleMap.updateMatrix(); } - } + uniforms.uvTransform.value.copy(uvScaleMap.matrix); + } + } - if ( geometry instanceof THREE.BufferGeometry ) { + function refreshUniformsSprites(uniforms, material) { + uniforms.diffuse.value.copy(material.color); + uniforms.opacity.value = material.opacity; + uniforms.rotation.value = material.rotation; - var material = object.material; + if (material.map) { + uniforms.map.value = material.map; + } - if ( material === undefined ) return intersects; + if (material.alphaMap) { + uniforms.alphaMap.value = material.alphaMap; + } // uv repeat and offset setting priorities + // 1. color map + // 2. alpha map - var attributes = geometry.attributes; - var a, b, c; - var precision = raycaster.precision; + var uvScaleMap; - if ( attributes.index !== undefined ) { + if (material.map) { + uvScaleMap = material.map; + } else if (material.alphaMap) { + uvScaleMap = material.alphaMap; + } - var indices = attributes.index.array; - var positions = attributes.position.array; - var offsets = geometry.offsets; + if (uvScaleMap !== undefined) { + if (uvScaleMap.matrixAutoUpdate === true) { + uvScaleMap.updateMatrix(); + } - if ( offsets.length === 0 ) { + uniforms.uvTransform.value.copy(uvScaleMap.matrix); + } + } - offsets = [ { start: 0, count: positions.length, index: 0 } ]; + function refreshUniformsLambert(uniforms, material) { + if (material.emissiveMap) { + uniforms.emissiveMap.value = material.emissiveMap; + } + } - } + function refreshUniformsPhong(uniforms, material) { + uniforms.specular.value.copy(material.specular); + uniforms.shininess.value = Math.max(material.shininess, 1e-4); // to prevent pow( 0.0, 0.0 ) - for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) { - - var start = offsets[ oi ].start; - var count = offsets[ oi ].count; - var index = offsets[ oi ].index; - - for ( var i = start, il = start + count; i < il; i += 3 ) { - - a = index + indices[ i ]; - b = index + indices[ i + 1 ]; - c = index + indices[ i + 2 ]; - - vA.set( - positions[ a * 3 ], - positions[ a * 3 + 1 ], - positions[ a * 3 + 2 ] - ); - vB.set( - positions[ b * 3 ], - positions[ b * 3 + 1 ], - positions[ b * 3 + 2 ] - ); - vC.set( - positions[ c * 3 ], - positions[ c * 3 + 1 ], - positions[ c * 3 + 2 ] - ); - - - if ( material.side === THREE.BackSide ) { - - var intersectionPoint = localRay.intersectTriangle( vC, vB, vA, true ); + if (material.emissiveMap) { + uniforms.emissiveMap.value = material.emissiveMap; + } - } else { + if (material.bumpMap) { + uniforms.bumpMap.value = material.bumpMap; + uniforms.bumpScale.value = material.bumpScale; + if (material.side === BackSide) uniforms.bumpScale.value *= -1; + } - var intersectionPoint = localRay.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide ); + if (material.normalMap) { + uniforms.normalMap.value = material.normalMap; + uniforms.normalScale.value.copy(material.normalScale); + if (material.side === BackSide) uniforms.normalScale.value.negate(); + } - } + if (material.displacementMap) { + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; + } + } - if ( intersectionPoint === null ) continue; + function refreshUniformsToon(uniforms, material) { + if (material.gradientMap) { + uniforms.gradientMap.value = material.gradientMap; + } - intersectionPoint.applyMatrix4( object.matrixWorld ); + if (material.emissiveMap) { + uniforms.emissiveMap.value = material.emissiveMap; + } - var distance = raycaster.ray.origin.distanceTo( intersectionPoint ); + if (material.bumpMap) { + uniforms.bumpMap.value = material.bumpMap; + uniforms.bumpScale.value = material.bumpScale; + if (material.side === BackSide) uniforms.bumpScale.value *= -1; + } - if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue; + if (material.normalMap) { + uniforms.normalMap.value = material.normalMap; + uniforms.normalScale.value.copy(material.normalScale); + if (material.side === BackSide) uniforms.normalScale.value.negate(); + } - intersects.push( { + if (material.displacementMap) { + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; + } + } - distance: distance, - point: intersectionPoint, - indices: [a, b, c], - face: null, - faceIndex: null, - object: object + function refreshUniformsStandard(uniforms, material) { + uniforms.roughness.value = material.roughness; + uniforms.metalness.value = material.metalness; - } ); + if (material.roughnessMap) { + uniforms.roughnessMap.value = material.roughnessMap; + } - } + if (material.metalnessMap) { + uniforms.metalnessMap.value = material.metalnessMap; + } - } + if (material.emissiveMap) { + uniforms.emissiveMap.value = material.emissiveMap; + } - } else { + if (material.bumpMap) { + uniforms.bumpMap.value = material.bumpMap; + uniforms.bumpScale.value = material.bumpScale; + if (material.side === BackSide) uniforms.bumpScale.value *= -1; + } - var offsets = geometry.offsets; - var positions = attributes.position.array; - - for ( var i = 0, il = attributes.position.array.length; i < il; i += 3 ) { - - a = i; - b = i + 1; - c = i + 2; - - vA.set( - positions[ a * 3 ], - positions[ a * 3 + 1 ], - positions[ a * 3 + 2 ] - ); - vB.set( - positions[ b * 3 ], - positions[ b * 3 + 1 ], - positions[ b * 3 + 2 ] - ); - vC.set( - positions[ c * 3 ], - positions[ c * 3 + 1 ], - positions[ c * 3 + 2 ] - ); - - - if ( material.side === THREE.BackSide ) { - - var intersectionPoint = localRay.intersectTriangle( vC, vB, vA, true ); + if (material.normalMap) { + uniforms.normalMap.value = material.normalMap; + uniforms.normalScale.value.copy(material.normalScale); + if (material.side === BackSide) uniforms.normalScale.value.negate(); + } - } else { + if (material.displacementMap) { + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; + } - var intersectionPoint = localRay.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide ); + var envMap = properties.get(material).envMap; - } + if (envMap) { + //uniforms.envMap.value = material.envMap; // part of uniforms common + uniforms.envMapIntensity.value = material.envMapIntensity; + } + } - if ( intersectionPoint === null ) continue; + function refreshUniformsPhysical(uniforms, material) { + refreshUniformsStandard(uniforms, material); + uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common - intersectionPoint.applyMatrix4( object.matrixWorld ); + uniforms.clearcoat.value = material.clearcoat; + uniforms.clearcoatRoughness.value = material.clearcoatRoughness; + if (material.sheen) uniforms.sheen.value.copy(material.sheen); - var distance = raycaster.ray.origin.distanceTo( intersectionPoint ); + if (material.clearcoatMap) { + uniforms.clearcoatMap.value = material.clearcoatMap; + } - if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue; + if (material.clearcoatRoughnessMap) { + uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; + } - intersects.push( { + if (material.clearcoatNormalMap) { + uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale); + uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; - distance: distance, - point: intersectionPoint, - indices: [a, b, c], - face: null, - faceIndex: null, - object: object + if (material.side === BackSide) { + uniforms.clearcoatNormalScale.value.negate(); + } + } - } ); + uniforms.transmission.value = material.transmission; - } + if (material.transmissionMap) { + uniforms.transmissionMap.value = material.transmissionMap; + } + } - } + function refreshUniformsMatcap(uniforms, material) { + if (material.matcap) { + uniforms.matcap.value = material.matcap; + } - } else if ( geometry instanceof THREE.Geometry ) { + if (material.bumpMap) { + uniforms.bumpMap.value = material.bumpMap; + uniforms.bumpScale.value = material.bumpScale; + if (material.side === BackSide) uniforms.bumpScale.value *= -1; + } - var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial; - var objectMaterials = isFaceMaterial === true ? object.material.materials : null; + if (material.normalMap) { + uniforms.normalMap.value = material.normalMap; + uniforms.normalScale.value.copy(material.normalScale); + if (material.side === BackSide) uniforms.normalScale.value.negate(); + } - var a, b, c, d; - var precision = raycaster.precision; + if (material.displacementMap) { + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; + } + } - var vertices = geometry.vertices; + function refreshUniformsDepth(uniforms, material) { + if (material.displacementMap) { + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; + } + } - for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) { + function refreshUniformsDistance(uniforms, material) { + if (material.displacementMap) { + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; + } - var face = geometry.faces[ f ]; + uniforms.referencePosition.value.copy(material.referencePosition); + uniforms.nearDistance.value = material.nearDistance; + uniforms.farDistance.value = material.farDistance; + } - var material = isFaceMaterial === true ? objectMaterials[ face.materialIndex ] : object.material; + function refreshUniformsNormal(uniforms, material) { + if (material.bumpMap) { + uniforms.bumpMap.value = material.bumpMap; + uniforms.bumpScale.value = material.bumpScale; + if (material.side === BackSide) uniforms.bumpScale.value *= -1; + } - if ( material === undefined ) continue; + if (material.normalMap) { + uniforms.normalMap.value = material.normalMap; + uniforms.normalScale.value.copy(material.normalScale); + if (material.side === BackSide) uniforms.normalScale.value.negate(); + } - a = vertices[ face.a ]; - b = vertices[ face.b ]; - c = vertices[ face.c ]; + if (material.displacementMap) { + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; + } + } - if ( material.morphTargets === true ) { + return { + refreshFogUniforms: refreshFogUniforms, + refreshMaterialUniforms: refreshMaterialUniforms + }; + } - var morphTargets = geometry.morphTargets; - var morphInfluences = object.morphTargetInfluences; + function WebGLRenderer(parameters) { + parameters = parameters || {}; - vA.set( 0, 0, 0 ); - vB.set( 0, 0, 0 ); - vC.set( 0, 0, 0 ); + var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas'), + _context = parameters.context !== undefined ? parameters.context : null, + _alpha = parameters.alpha !== undefined ? parameters.alpha : false, + _depth = parameters.depth !== undefined ? parameters.depth : true, + _stencil = parameters.stencil !== undefined ? parameters.stencil : true, + _antialias = parameters.antialias !== undefined ? parameters.antialias : false, + _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true, + _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, + _powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default', + _failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== undefined ? parameters.failIfMajorPerformanceCaveat : false; - for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) { + var currentRenderList = null; + var currentRenderState = null; // public properties - var influence = morphInfluences[ t ]; + this.domElement = _canvas; // Debug configuration container - if ( influence === 0 ) continue; + this.debug = { + /** + * Enables error checking and reporting when shader programs are being compiled + * @type {boolean} + */ + checkShaderErrors: true + }; // clearing - var targets = morphTargets[ t ].vertices; + this.autoClear = true; + this.autoClearColor = true; + this.autoClearDepth = true; + this.autoClearStencil = true; // scene graph - vA.x += ( targets[ face.a ].x - a.x ) * influence; - vA.y += ( targets[ face.a ].y - a.y ) * influence; - vA.z += ( targets[ face.a ].z - a.z ) * influence; + this.sortObjects = true; // user-defined clipping - vB.x += ( targets[ face.b ].x - b.x ) * influence; - vB.y += ( targets[ face.b ].y - b.y ) * influence; - vB.z += ( targets[ face.b ].z - b.z ) * influence; + this.clippingPlanes = []; + this.localClippingEnabled = false; // physically based shading - vC.x += ( targets[ face.c ].x - c.x ) * influence; - vC.y += ( targets[ face.c ].y - c.y ) * influence; - vC.z += ( targets[ face.c ].z - c.z ) * influence; + this.gammaFactor = 2.0; // for backwards compatibility - } + this.outputEncoding = LinearEncoding; // physical lights - vA.add( a ); - vB.add( b ); - vC.add( c ); + this.physicallyCorrectLights = false; // tone mapping - a = vA; - b = vB; - c = vC; + this.toneMapping = NoToneMapping; + this.toneMappingExposure = 1.0; // morphs - } + this.maxMorphTargets = 8; + this.maxMorphNormals = 4; // internal properties - if ( material.side === THREE.BackSide ) { - - var intersectionPoint = localRay.intersectTriangle( c, b, a, true ); + var _this = this; - } else { - - var intersectionPoint = localRay.intersectTriangle( a, b, c, material.side !== THREE.DoubleSide ); + var _isContextLost = false; // internal state cache - } + var _framebuffer = null; + var _currentActiveCubeFace = 0; + var _currentActiveMipmapLevel = 0; + var _currentRenderTarget = null; + var _currentFramebuffer = null; - if ( intersectionPoint === null ) continue; + var _currentMaterialId = -1; - intersectionPoint.applyMatrix4( object.matrixWorld ); + var _currentCamera = null; + var _currentArrayCamera = null; - var distance = raycaster.ray.origin.distanceTo( intersectionPoint ); + var _currentViewport = new Vector4(); - if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue; + var _currentScissor = new Vector4(); - intersects.push( { + var _currentScissorTest = null; // - distance: distance, - point: intersectionPoint, - face: face, - faceIndex: f, - object: object + var _width = _canvas.width; + var _height = _canvas.height; + var _pixelRatio = 1; + var _opaqueSort = null; + var _transparentSort = null; - } ); + var _viewport = new Vector4(0, 0, _width, _height); - } + var _scissor = new Vector4(0, 0, _width, _height); - } + var _scissorTest = false; // frustum - } else if ( object instanceof THREE.Line ) { + var _frustum = new Frustum(); // clipping - var precision = raycaster.linePrecision; - var precisionSq = precision * precision; - var geometry = object.geometry; + var _clippingEnabled = false; + var _localClippingEnabled = false; // camera matrices cache - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + var _projScreenMatrix = new Matrix4(); - // Checking boundingSphere distance to ray + var _vector3 = new Vector3(); - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( object.matrixWorld ); - - if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) { + var _emptyScene = { + background: null, + fog: null, + environment: null, + overrideMaterial: null, + isScene: true + }; - return intersects; + function getTargetPixelRatio() { + return _currentRenderTarget === null ? _pixelRatio : 1; + } // initialize - } - - inverseMatrix.getInverse( object.matrixWorld ); - localRay.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); - /* if ( geometry instanceof THREE.BufferGeometry ) { + var _gl = _context; - } else */ if ( geometry instanceof THREE.Geometry ) { + function getContext(contextNames, contextAttributes) { + for (var i = 0; i < contextNames.length; i++) { + var contextName = contextNames[i]; - var vertices = geometry.vertices; - var nbVertices = vertices.length; - var interSegment = new THREE.Vector3(); - var interRay = new THREE.Vector3(); - var step = object.type === THREE.LineStrip ? 1 : 2; + var context = _canvas.getContext(contextName, contextAttributes); - for ( var i = 0; i < nbVertices - 1; i = i + step ) { + if (context !== null) return context; + } - var distSq = localRay.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); + return null; + } - if ( distSq > precisionSq ) continue; + try { + var contextAttributes = { + alpha: _alpha, + depth: _depth, + stencil: _stencil, + antialias: _antialias, + premultipliedAlpha: _premultipliedAlpha, + preserveDrawingBuffer: _preserveDrawingBuffer, + powerPreference: _powerPreference, + failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat + }; // event listeners must be registered before WebGL context is created, see #12753 - var distance = localRay.origin.distanceTo( interRay ); + _canvas.addEventListener('webglcontextlost', onContextLost, false); - if ( distance < raycaster.near || distance > raycaster.far ) continue; + _canvas.addEventListener('webglcontextrestored', onContextRestore, false); - intersects.push( { + if (_gl === null) { + var contextNames = ['webgl2', 'webgl', 'experimental-webgl']; - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4( object.matrixWorld ), - face: null, - faceIndex: null, - object: object + if (_this.isWebGL1Renderer === true) { + contextNames.shift(); + } - } ); + _gl = getContext(contextNames, contextAttributes); + if (_gl === null) { + if (getContext(contextNames)) { + throw new Error('Error creating WebGL context with your selected attributes.'); + } else { + throw new Error('Error creating WebGL context.'); + } } + } // Some experimental-webgl implementations do not have getShaderPrecisionFormat + + if (_gl.getShaderPrecisionFormat === undefined) { + _gl.getShaderPrecisionFormat = function () { + return { + 'rangeMin': 1, + 'rangeMax': 1, + 'precision': 1 + }; + }; } + } catch (error) { + console.error('THREE.WebGLRenderer: ' + error.message); + throw error; + } + + var extensions, capabilities, state, info; + var properties, textures, cubemaps, attributes, geometries, objects; + var programCache, materials, renderLists, renderStates, clipping; + var background, morphtargets, bufferRenderer, indexedBufferRenderer; + var utils, bindingStates; + + function initGLContext() { + extensions = new WebGLExtensions(_gl); + capabilities = new WebGLCapabilities(_gl, extensions, parameters); + + if (capabilities.isWebGL2 === false) { + extensions.get('WEBGL_depth_texture'); + extensions.get('OES_texture_float'); + extensions.get('OES_texture_half_float'); + extensions.get('OES_texture_half_float_linear'); + extensions.get('OES_standard_derivatives'); + extensions.get('OES_element_index_uint'); + extensions.get('OES_vertex_array_object'); + extensions.get('ANGLE_instanced_arrays'); + } + + extensions.get('OES_texture_float_linear'); + utils = new WebGLUtils(_gl, extensions, capabilities); + state = new WebGLState(_gl, extensions, capabilities); + state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor()); + state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor()); + info = new WebGLInfo(_gl); + properties = new WebGLProperties(); + textures = new WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info); + cubemaps = new WebGLCubeMaps(_this); + attributes = new WebGLAttributes(_gl, capabilities); + bindingStates = new WebGLBindingStates(_gl, extensions, attributes, capabilities); + geometries = new WebGLGeometries(_gl, attributes, info, bindingStates); + objects = new WebGLObjects(_gl, geometries, attributes, info); + morphtargets = new WebGLMorphtargets(_gl); + clipping = new WebGLClipping(properties); + programCache = new WebGLPrograms(_this, cubemaps, extensions, capabilities, bindingStates, clipping); + materials = new WebGLMaterials(properties); + renderLists = new WebGLRenderLists(properties); + renderStates = new WebGLRenderStates(extensions, capabilities); + background = new WebGLBackground(_this, cubemaps, state, objects, _premultipliedAlpha); + bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info, capabilities); + indexedBufferRenderer = new WebGLIndexedBufferRenderer(_gl, extensions, info, capabilities); + info.programs = programCache.programs; + _this.capabilities = capabilities; + _this.extensions = extensions; + _this.properties = properties; + _this.renderLists = renderLists; + _this.state = state; + _this.info = info; + } + + initGLContext(); // xr + + var xr = new WebXRManager(_this, _gl); + this.xr = xr; // shadow map + + var shadowMap = new WebGLShadowMap(_this, objects, capabilities.maxTextureSize); + this.shadowMap = shadowMap; // API + + this.getContext = function () { + return _gl; + }; - } + this.getContextAttributes = function () { + return _gl.getContextAttributes(); + }; - }; + this.forceContextLoss = function () { + var extension = extensions.get('WEBGL_lose_context'); + if (extension) extension.loseContext(); + }; - var intersectDescendants = function ( object, raycaster, intersects ) { + this.forceContextRestore = function () { + var extension = extensions.get('WEBGL_lose_context'); + if (extension) extension.restoreContext(); + }; - var descendants = object.getDescendants(); + this.getPixelRatio = function () { + return _pixelRatio; + }; - for ( var i = 0, l = descendants.length; i < l; i ++ ) { + this.setPixelRatio = function (value) { + if (value === undefined) return; + _pixelRatio = value; + this.setSize(_width, _height, false); + }; - intersectObject( descendants[ i ], raycaster, intersects ); + this.getSize = function (target) { + if (target === undefined) { + console.warn('WebGLRenderer: .getsize() now requires a Vector2 as an argument'); + target = new Vector2(); + } - } - }; + return target.set(_width, _height); + }; - // + this.setSize = function (width, height, updateStyle) { + if (xr.isPresenting) { + console.warn('THREE.WebGLRenderer: Can\'t change size while VR device is presenting.'); + return; + } - THREE.Raycaster.prototype.precision = 0.0001; - THREE.Raycaster.prototype.linePrecision = 1; + _width = width; + _height = height; + _canvas.width = Math.floor(width * _pixelRatio); + _canvas.height = Math.floor(height * _pixelRatio); - THREE.Raycaster.prototype.set = function ( origin, direction ) { + if (updateStyle !== false) { + _canvas.style.width = width + 'px'; + _canvas.style.height = height + 'px'; + } - this.ray.set( origin, direction ); - // direction is assumed to be normalized (for accurate distance calculations) + this.setViewport(0, 0, width, height); + }; - }; + this.getDrawingBufferSize = function (target) { + if (target === undefined) { + console.warn('WebGLRenderer: .getdrawingBufferSize() now requires a Vector2 as an argument'); + target = new Vector2(); + } - THREE.Raycaster.prototype.intersectObject = function ( object, recursive ) { + return target.set(_width * _pixelRatio, _height * _pixelRatio).floor(); + }; - var intersects = []; + this.setDrawingBufferSize = function (width, height, pixelRatio) { + _width = width; + _height = height; + _pixelRatio = pixelRatio; + _canvas.width = Math.floor(width * pixelRatio); + _canvas.height = Math.floor(height * pixelRatio); + this.setViewport(0, 0, width, height); + }; - if ( recursive === true ) { + this.getCurrentViewport = function (target) { + if (target === undefined) { + console.warn('WebGLRenderer: .getCurrentViewport() now requires a Vector4 as an argument'); + target = new Vector4(); + } - intersectDescendants( object, this, intersects ); + return target.copy(_currentViewport); + }; - } + this.getViewport = function (target) { + return target.copy(_viewport); + }; - intersectObject( object, this, intersects ); + this.setViewport = function (x, y, width, height) { + if (x.isVector4) { + _viewport.set(x.x, x.y, x.z, x.w); + } else { + _viewport.set(x, y, width, height); + } - intersects.sort( descSort ); + state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor()); + }; - return intersects; + this.getScissor = function (target) { + return target.copy(_scissor); + }; - }; + this.setScissor = function (x, y, width, height) { + if (x.isVector4) { + _scissor.set(x.x, x.y, x.z, x.w); + } else { + _scissor.set(x, y, width, height); + } - THREE.Raycaster.prototype.intersectObjects = function ( objects, recursive ) { + state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor()); + }; - var intersects = []; + this.getScissorTest = function () { + return _scissorTest; + }; - for ( var i = 0, l = objects.length; i < l; i ++ ) { + this.setScissorTest = function (boolean) { + state.setScissorTest(_scissorTest = boolean); + }; - intersectObject( objects[ i ], this, intersects ); + this.setOpaqueSort = function (method) { + _opaqueSort = method; + }; - if ( recursive === true ) { + this.setTransparentSort = function (method) { + _transparentSort = method; + }; // Clearing - intersectDescendants( objects[ i ], this, intersects ); - } + this.getClearColor = function () { + return background.getClearColor(); + }; - } + this.setClearColor = function () { + background.setClearColor.apply(background, arguments); + }; - intersects.sort( descSort ); + this.getClearAlpha = function () { + return background.getClearAlpha(); + }; - return intersects; + this.setClearAlpha = function () { + background.setClearAlpha.apply(background, arguments); + }; - }; + this.clear = function (color, depth, stencil) { + var bits = 0; + if (color === undefined || color) bits |= 16384; + if (depth === undefined || depth) bits |= 256; + if (stencil === undefined || stencil) bits |= 1024; -}( THREE ) ); + _gl.clear(bits); + }; -/** - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - * @author WestLangley / http://github.com/WestLangley - */ + this.clearColor = function () { + this.clear(true, false, false); + }; -THREE.Object3D = function () { + this.clearDepth = function () { + this.clear(false, true, false); + }; - this.id = THREE.Object3DIdCount ++; - this.uuid = THREE.Math.generateUUID(); + this.clearStencil = function () { + this.clear(false, false, true); + }; // - this.name = ''; - this.parent = undefined; - this.children = []; + this.dispose = function () { + _canvas.removeEventListener('webglcontextlost', onContextLost, false); - this.up = new THREE.Vector3( 0, 1, 0 ); + _canvas.removeEventListener('webglcontextrestored', onContextRestore, false); - this.position = new THREE.Vector3(); + renderLists.dispose(); + renderStates.dispose(); + properties.dispose(); + cubemaps.dispose(); + objects.dispose(); + bindingStates.dispose(); + xr.dispose(); + animation.stop(); + }; // Events - var scope = this; - Object.defineProperties( this, { - rotation: { - enumerable: true, - value: new THREE.Euler().onChange( function () { - scope.quaternion.setFromEuler( scope.rotation, false ); - } ) - }, - quaternion: { - enumerable: true, - value: new THREE.Quaternion().onChange( function () { - scope.rotation.setFromQuaternion( scope.quaternion, undefined, false ); - } ) - }, - scale: { - enumerable: true, - value: new THREE.Vector3( 1, 1, 1 ) + function onContextLost(event) { + event.preventDefault(); + console.log('THREE.WebGLRenderer: Context Lost.'); + _isContextLost = true; } - } ); - this.renderDepth = null; - - this.rotationAutoUpdate = true; + function onContextRestore() + /* event */ + { + console.log('THREE.WebGLRenderer: Context Restored.'); + _isContextLost = false; + initGLContext(); + } - this.matrix = new THREE.Matrix4(); - this.matrixWorld = new THREE.Matrix4(); + function onMaterialDispose(event) { + var material = event.target; + material.removeEventListener('dispose', onMaterialDispose); + deallocateMaterial(material); + } // Buffer deallocation - this.matrixAutoUpdate = true; - this.matrixWorldNeedsUpdate = false; - this.visible = true; + function deallocateMaterial(material) { + releaseMaterialProgramReference(material); + properties.remove(material); + } - this.castShadow = false; - this.receiveShadow = false; + function releaseMaterialProgramReference(material) { + var programInfo = properties.get(material).program; - this.frustumCulled = true; + if (programInfo !== undefined) { + programCache.releaseProgram(programInfo); + } + } // Buffer rendering - this.userData = {}; -}; + function renderObjectImmediate(object, program) { + object.render(function (object) { + _this.renderBufferImmediate(object, program); + }); + } + this.renderBufferImmediate = function (object, program) { + bindingStates.initAttributes(); + var buffers = properties.get(object); + if (object.hasPositions && !buffers.position) buffers.position = _gl.createBuffer(); + if (object.hasNormals && !buffers.normal) buffers.normal = _gl.createBuffer(); + if (object.hasUvs && !buffers.uv) buffers.uv = _gl.createBuffer(); + if (object.hasColors && !buffers.color) buffers.color = _gl.createBuffer(); + var programAttributes = program.getAttributes(); -THREE.Object3D.prototype = { + if (object.hasPositions) { + _gl.bindBuffer(34962, buffers.position); - constructor: THREE.Object3D, + _gl.bufferData(34962, object.positionArray, 35048); - get eulerOrder () { + bindingStates.enableAttribute(programAttributes.position); - console.warn( 'DEPRECATED: Object3D\'s .eulerOrder has been moved to Object3D\'s .rotation.order.' ); + _gl.vertexAttribPointer(programAttributes.position, 3, 5126, false, 0, 0); + } - return this.rotation.order; + if (object.hasNormals) { + _gl.bindBuffer(34962, buffers.normal); - }, + _gl.bufferData(34962, object.normalArray, 35048); - set eulerOrder ( value ) { + bindingStates.enableAttribute(programAttributes.normal); - console.warn( 'DEPRECATED: Object3D\'s .eulerOrder has been moved to Object3D\'s .rotation.order.' ); + _gl.vertexAttribPointer(programAttributes.normal, 3, 5126, false, 0, 0); + } - this.rotation.order = value; + if (object.hasUvs) { + _gl.bindBuffer(34962, buffers.uv); - }, + _gl.bufferData(34962, object.uvArray, 35048); - get useQuaternion () { + bindingStates.enableAttribute(programAttributes.uv); - console.warn( 'DEPRECATED: Object3D\'s .useQuaternion has been removed. The library now uses quaternions by default.' ); + _gl.vertexAttribPointer(programAttributes.uv, 2, 5126, false, 0, 0); + } - }, + if (object.hasColors) { + _gl.bindBuffer(34962, buffers.color); - set useQuaternion ( value ) { + _gl.bufferData(34962, object.colorArray, 35048); - console.warn( 'DEPRECATED: Object3D\'s .useQuaternion has been removed. The library now uses quaternions by default.' ); + bindingStates.enableAttribute(programAttributes.color); - }, + _gl.vertexAttribPointer(programAttributes.color, 3, 5126, false, 0, 0); + } - applyMatrix: function ( matrix ) { + bindingStates.disableUnusedAttributes(); - this.matrix.multiplyMatrices( matrix, this.matrix ); + _gl.drawArrays(4, 0, object.count); - this.matrix.decompose( this.position, this.quaternion, this.scale ); + object.count = 0; + }; - }, + this.renderBufferDirect = function (camera, scene, geometry, material, object, group) { + if (scene === null) scene = _emptyScene; // renderBufferDirect second parameter used to be fog (could be null) - setRotationFromAxisAngle: function ( axis, angle ) { + var frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; + var program = setProgram(camera, scene, material, object); + state.setMaterial(material, frontFaceCW); // - // assumes axis is normalized + var index = geometry.index; + var position = geometry.attributes.position; // - this.quaternion.setFromAxisAngle( axis, angle ); + if (index === null) { + if (position === undefined || position.count === 0) return; + } else if (index.count === 0) { + return; + } // - }, - setRotationFromEuler: function ( euler ) { + var rangeFactor = 1; - this.quaternion.setFromEuler( euler, true ); + if (material.wireframe === true) { + index = geometries.getWireframeAttribute(geometry); + rangeFactor = 2; + } - }, + if (material.morphTargets || material.morphNormals) { + morphtargets.update(object, geometry, material, program); + } - setRotationFromMatrix: function ( m ) { + bindingStates.setup(object, material, program, geometry, index); + var attribute; + var renderer = bufferRenderer; - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + if (index !== null) { + attribute = attributes.get(index); + renderer = indexedBufferRenderer; + renderer.setIndex(attribute); + } // - this.quaternion.setFromRotationMatrix( m ); - }, + var dataCount = index !== null ? index.count : position.count; + var rangeStart = geometry.drawRange.start * rangeFactor; + var rangeCount = geometry.drawRange.count * rangeFactor; + var groupStart = group !== null ? group.start * rangeFactor : 0; + var groupCount = group !== null ? group.count * rangeFactor : Infinity; + var drawStart = Math.max(rangeStart, groupStart); + var drawEnd = Math.min(dataCount, rangeStart + rangeCount, groupStart + groupCount) - 1; + var drawCount = Math.max(0, drawEnd - drawStart + 1); + if (drawCount === 0) return; // - setRotationFromQuaternion: function ( q ) { + if (object.isMesh) { + if (material.wireframe === true) { + state.setLineWidth(material.wireframeLinewidth * getTargetPixelRatio()); + renderer.setMode(1); + } else { + renderer.setMode(4); + } + } else if (object.isLine) { + var lineWidth = material.linewidth; + if (lineWidth === undefined) lineWidth = 1; // Not using Line*Material - // assumes q is normalized + state.setLineWidth(lineWidth * getTargetPixelRatio()); - this.quaternion.copy( q ); + if (object.isLineSegments) { + renderer.setMode(1); + } else if (object.isLineLoop) { + renderer.setMode(2); + } else { + renderer.setMode(3); + } + } else if (object.isPoints) { + renderer.setMode(0); + } else if (object.isSprite) { + renderer.setMode(4); + } - }, + if (object.isInstancedMesh) { + renderer.renderInstances(drawStart, drawCount, object.count); + } else if (geometry.isInstancedBufferGeometry) { + var instanceCount = Math.min(geometry.instanceCount, geometry._maxInstanceCount); + renderer.renderInstances(drawStart, drawCount, instanceCount); + } else { + renderer.render(drawStart, drawCount); + } + }; // Compile - rotateOnAxis: function() { - // rotate object on axis in object space - // axis is assumed to be normalized + this.compile = function (scene, camera) { + currentRenderState = renderStates.get(scene, camera); + currentRenderState.init(); + scene.traverseVisible(function (object) { + if (object.isLight && object.layers.test(camera.layers)) { + currentRenderState.pushLight(object); - var q1 = new THREE.Quaternion(); + if (object.castShadow) { + currentRenderState.pushShadow(object); + } + } + }); + currentRenderState.setupLights(camera); + var compiled = new WeakMap(); + scene.traverse(function (object) { + var material = object.material; - return function ( axis, angle ) { + if (material) { + if (Array.isArray(material)) { + for (var i = 0; i < material.length; i++) { + var material2 = material[i]; - q1.setFromAxisAngle( axis, angle ); + if (compiled.has(material2) === false) { + initMaterial(material2, scene, object); + compiled.set(material2); + } + } + } else if (compiled.has(material) === false) { + initMaterial(material, scene, object); + compiled.set(material); + } + } + }); + }; // Animation Loop - this.quaternion.multiply( q1 ); - return this; + var onAnimationFrameCallback = null; + function onAnimationFrame(time) { + if (xr.isPresenting) return; + if (onAnimationFrameCallback) onAnimationFrameCallback(time); } - }(), - - rotateX: function () { + var animation = new WebGLAnimation(); + animation.setAnimationLoop(onAnimationFrame); + if (typeof window !== 'undefined') animation.setContext(window); - var v1 = new THREE.Vector3( 1, 0, 0 ); + this.setAnimationLoop = function (callback) { + onAnimationFrameCallback = callback; + xr.setAnimationLoop(callback); + callback === null ? animation.stop() : animation.start(); + }; // Rendering - return function ( angle ) { - return this.rotateOnAxis( v1, angle ); + this.render = function (scene, camera) { + var renderTarget, forceClear; - }; - - }(), - - rotateY: function () { - - var v1 = new THREE.Vector3( 0, 1, 0 ); - - return function ( angle ) { - - return this.rotateOnAxis( v1, angle ); + if (arguments[2] !== undefined) { + console.warn('THREE.WebGLRenderer.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.'); + renderTarget = arguments[2]; + } - }; + if (arguments[3] !== undefined) { + console.warn('THREE.WebGLRenderer.render(): the forceClear argument has been removed. Use .clear() instead.'); + forceClear = arguments[3]; + } - }(), + if (camera !== undefined && camera.isCamera !== true) { + console.error('THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.'); + return; + } - rotateZ: function () { + if (_isContextLost === true) return; // reset caching for this frame - var v1 = new THREE.Vector3( 0, 0, 1 ); + bindingStates.resetDefaultState(); + _currentMaterialId = -1; + _currentCamera = null; // update scene graph - return function ( angle ) { + if (scene.autoUpdate === true) scene.updateMatrixWorld(); // update camera matrices and frustum - return this.rotateOnAxis( v1, angle ); + if (camera.parent === null) camera.updateMatrixWorld(); - }; + if (xr.enabled === true && xr.isPresenting === true) { + camera = xr.getCamera(camera); + } // - }(), - translateOnAxis: function () { + if (scene.isScene === true) scene.onBeforeRender(_this, scene, camera, renderTarget || _currentRenderTarget); + currentRenderState = renderStates.get(scene, camera); + currentRenderState.init(); - // translate object by distance along axis in object space - // axis is assumed to be normalized + _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); - var v1 = new THREE.Vector3(); + _frustum.setFromProjectionMatrix(_projScreenMatrix); - return function ( axis, distance ) { + _localClippingEnabled = this.localClippingEnabled; + _clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled, camera); + currentRenderList = renderLists.get(scene, camera); + currentRenderList.init(); + projectObject(scene, camera, 0, _this.sortObjects); + currentRenderList.finish(); - v1.copy( axis ); + if (_this.sortObjects === true) { + currentRenderList.sort(_opaqueSort, _transparentSort); + } // - v1.applyQuaternion( this.quaternion ); - this.position.add( v1.multiplyScalar( distance ) ); + if (_clippingEnabled === true) clipping.beginShadows(); + var shadowsArray = currentRenderState.state.shadowsArray; + shadowMap.render(shadowsArray, scene, camera); + currentRenderState.setupLights(camera); + if (_clippingEnabled === true) clipping.endShadows(); // - return this; + if (this.info.autoReset === true) this.info.reset(); - } + if (renderTarget !== undefined) { + this.setRenderTarget(renderTarget); + } // - }(), - translate: function ( distance, axis ) { + background.render(currentRenderList, scene, camera, forceClear); // render scene - console.warn( 'DEPRECATED: Object3D\'s .translate() has been removed. Use .translateOnAxis( axis, distance ) instead. Note args have been changed.' ); - return this.translateOnAxis( axis, distance ); + var opaqueObjects = currentRenderList.opaque; + var transparentObjects = currentRenderList.transparent; + if (opaqueObjects.length > 0) renderObjects(opaqueObjects, scene, camera); + if (transparentObjects.length > 0) renderObjects(transparentObjects, scene, camera); // - }, + if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); // - translateX: function () { + if (_currentRenderTarget !== null) { + // Generate mipmap if we're using any kind of mipmap filtering + textures.updateRenderTargetMipmap(_currentRenderTarget); // resolve multisample renderbuffers to a single-sample texture if necessary - var v1 = new THREE.Vector3( 1, 0, 0 ); + textures.updateMultisampleRenderTarget(_currentRenderTarget); + } // Ensure depth buffer writing is enabled so it can be cleared on next render - return function ( distance ) { - return this.translateOnAxis( v1, distance ); + state.buffers.depth.setTest(true); + state.buffers.depth.setMask(true); + state.buffers.color.setMask(true); + state.setPolygonOffset(false); // _gl.finish(); + currentRenderList = null; + currentRenderState = null; }; - }(), - - translateY: function () { - - var v1 = new THREE.Vector3( 0, 1, 0 ); + function projectObject(object, camera, groupOrder, sortObjects) { + if (object.visible === false) return; + var visible = object.layers.test(camera.layers); - return function ( distance ) { + if (visible) { + if (object.isGroup) { + groupOrder = object.renderOrder; + } else if (object.isLOD) { + if (object.autoUpdate === true) object.update(camera); + } else if (object.isLight) { + currentRenderState.pushLight(object); - return this.translateOnAxis( v1, distance ); + if (object.castShadow) { + currentRenderState.pushShadow(object); + } + } else if (object.isSprite) { + if (!object.frustumCulled || _frustum.intersectsSprite(object)) { + if (sortObjects) { + _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); + } - }; + var geometry = objects.update(object); + var material = object.material; - }(), + if (material.visible) { + currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null); + } + } + } else if (object.isImmediateRenderObject) { + if (sortObjects) { + _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); + } - translateZ: function () { + currentRenderList.push(object, null, object.material, groupOrder, _vector3.z, null); + } else if (object.isMesh || object.isLine || object.isPoints) { + if (object.isSkinnedMesh) { + // update skeleton only once in a frame + if (object.skeleton.frame !== info.render.frame) { + object.skeleton.update(); + object.skeleton.frame = info.render.frame; + } + } - var v1 = new THREE.Vector3( 0, 0, 1 ); + if (!object.frustumCulled || _frustum.intersectsObject(object)) { + if (sortObjects) { + _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); + } - return function ( distance ) { + var _geometry = objects.update(object); - return this.translateOnAxis( v1, distance ); + var _material = object.material; - }; + if (Array.isArray(_material)) { + var groups = _geometry.groups; - }(), + for (var i = 0, l = groups.length; i < l; i++) { + var group = groups[i]; + var groupMaterial = _material[group.materialIndex]; - localToWorld: function ( vector ) { + if (groupMaterial && groupMaterial.visible) { + currentRenderList.push(object, _geometry, groupMaterial, groupOrder, _vector3.z, group); + } + } + } else if (_material.visible) { + currentRenderList.push(object, _geometry, _material, groupOrder, _vector3.z, null); + } + } + } + } - return vector.applyMatrix4( this.matrixWorld ); + var children = object.children; - }, + for (var _i = 0, _l = children.length; _i < _l; _i++) { + projectObject(children[_i], camera, groupOrder, sortObjects); + } + } - worldToLocal: function () { + function renderObjects(renderList, scene, camera) { + var overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null; - var m1 = new THREE.Matrix4(); + for (var i = 0, l = renderList.length; i < l; i++) { + var renderItem = renderList[i]; + var object = renderItem.object; + var geometry = renderItem.geometry; + var material = overrideMaterial === null ? renderItem.material : overrideMaterial; + var group = renderItem.group; - return function ( vector ) { + if (camera.isArrayCamera) { + _currentArrayCamera = camera; + var cameras = camera.cameras; - return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) ); + for (var j = 0, jl = cameras.length; j < jl; j++) { + var camera2 = cameras[j]; - }; + if (object.layers.test(camera2.layers)) { + state.viewport(_currentViewport.copy(camera2.viewport)); + currentRenderState.setupLights(camera2); + renderObject(object, scene, camera2, geometry, material, group); + } + } + } else { + _currentArrayCamera = null; + renderObject(object, scene, camera, geometry, material, group); + } + } + } - }(), + function renderObject(object, scene, camera, geometry, material, group) { + object.onBeforeRender(_this, scene, camera, geometry, material, group); + currentRenderState = renderStates.get(scene, _currentArrayCamera || camera); + object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld); + object.normalMatrix.getNormalMatrix(object.modelViewMatrix); - lookAt: function () { + if (object.isImmediateRenderObject) { + var program = setProgram(camera, scene, material, object); + state.setMaterial(material); + bindingStates.reset(); + renderObjectImmediate(object, program); + } else { + _this.renderBufferDirect(camera, scene, geometry, material, object, group); + } + + object.onAfterRender(_this, scene, camera, geometry, material, group); + currentRenderState = renderStates.get(scene, _currentArrayCamera || camera); + } + + function initMaterial(material, scene, object) { + if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... + + var materialProperties = properties.get(material); + var lights = currentRenderState.state.lights; + var shadowsArray = currentRenderState.state.shadowsArray; + var lightsStateVersion = lights.state.version; + var parameters = programCache.getParameters(material, lights.state, shadowsArray, scene, object); + var programCacheKey = programCache.getProgramCacheKey(parameters); + var program = materialProperties.program; + var programChange = true; + + if (program === undefined) { + // new material + material.addEventListener('dispose', onMaterialDispose); + } else if (program.cacheKey !== programCacheKey) { + // changed glsl or parameters + releaseMaterialProgramReference(material); + } else if (materialProperties.lightsStateVersion !== lightsStateVersion) { + programChange = false; + } else if (parameters.shaderID !== undefined) { + // same glsl and uniform list, envMap still needs the update here to avoid a frame-late effect + var environment = material.isMeshStandardMaterial ? scene.environment : null; + materialProperties.envMap = cubemaps.get(material.envMap || environment); + return; + } else { + // only rebuild uniform list + programChange = false; + } + + if (programChange) { + parameters.uniforms = programCache.getUniforms(material); + material.onBeforeCompile(parameters, _this); + program = programCache.acquireProgram(parameters, programCacheKey); + materialProperties.program = program; + materialProperties.uniforms = parameters.uniforms; + materialProperties.outputEncoding = parameters.outputEncoding; + } + + var uniforms = materialProperties.uniforms; + + if (!material.isShaderMaterial && !material.isRawShaderMaterial || material.clipping === true) { + materialProperties.numClippingPlanes = clipping.numPlanes; + materialProperties.numIntersection = clipping.numIntersection; + uniforms.clippingPlanes = clipping.uniform; + } + + materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null; + materialProperties.fog = scene.fog; + materialProperties.envMap = cubemaps.get(material.envMap || materialProperties.environment); // store the light setup it was created for + + materialProperties.needsLights = materialNeedsLights(material); + materialProperties.lightsStateVersion = lightsStateVersion; + + if (materialProperties.needsLights) { + // wire up the material to this renderer's lighting state + uniforms.ambientLightColor.value = lights.state.ambient; + uniforms.lightProbe.value = lights.state.probe; + uniforms.directionalLights.value = lights.state.directional; + uniforms.directionalLightShadows.value = lights.state.directionalShadow; + uniforms.spotLights.value = lights.state.spot; + uniforms.spotLightShadows.value = lights.state.spotShadow; + uniforms.rectAreaLights.value = lights.state.rectArea; + uniforms.ltc_1.value = lights.state.rectAreaLTC1; + uniforms.ltc_2.value = lights.state.rectAreaLTC2; + uniforms.pointLights.value = lights.state.point; + uniforms.pointLightShadows.value = lights.state.pointShadow; + uniforms.hemisphereLights.value = lights.state.hemi; + uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; + uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; + uniforms.spotShadowMap.value = lights.state.spotShadowMap; + uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix; + uniforms.pointShadowMap.value = lights.state.pointShadowMap; + uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; // TODO (abelnation): add area lights shadow info to uniforms + } + + var progUniforms = materialProperties.program.getUniforms(); + var uniformsList = WebGLUniforms.seqWithValue(progUniforms.seq, uniforms); + materialProperties.uniformsList = uniformsList; + } + + function setProgram(camera, scene, material, object) { + if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... + + textures.resetTextureUnits(); + var fog = scene.fog; + var environment = material.isMeshStandardMaterial ? scene.environment : null; + var encoding = _currentRenderTarget === null ? _this.outputEncoding : _currentRenderTarget.texture.encoding; + var envMap = cubemaps.get(material.envMap || environment); + var materialProperties = properties.get(material); + var lights = currentRenderState.state.lights; + + if (_clippingEnabled === true) { + if (_localClippingEnabled === true || camera !== _currentCamera) { + var useCache = camera === _currentCamera && material.id === _currentMaterialId; // we might want to call this function with some ClippingGroup + // object instead of the material, once it becomes feasible + // (#8465, #8379) + + clipping.setState(material, camera, useCache); + } + } - // This routine does not support objects with rotated and/or translated parent(s) + if (material.version === materialProperties.__version) { + if (material.fog && materialProperties.fog !== fog) { + initMaterial(material, scene, object); + } else if (materialProperties.environment !== environment) { + initMaterial(material, scene, object); + } else if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) { + initMaterial(material, scene, object); + } else if (materialProperties.numClippingPlanes !== undefined && (materialProperties.numClippingPlanes !== clipping.numPlanes || materialProperties.numIntersection !== clipping.numIntersection)) { + initMaterial(material, scene, object); + } else if (materialProperties.outputEncoding !== encoding) { + initMaterial(material, scene, object); + } else if (materialProperties.envMap !== envMap) { + initMaterial(material, scene, object); + } + } else { + initMaterial(material, scene, object); + materialProperties.__version = material.version; + } - var m1 = new THREE.Matrix4(); + var refreshProgram = false; + var refreshMaterial = false; + var refreshLights = false; + var program = materialProperties.program, + p_uniforms = program.getUniforms(), + m_uniforms = materialProperties.uniforms; - return function ( vector ) { + if (state.useProgram(program.program)) { + refreshProgram = true; + refreshMaterial = true; + refreshLights = true; + } - m1.lookAt( vector, this.position, this.up ); + if (material.id !== _currentMaterialId) { + _currentMaterialId = material.id; + refreshMaterial = true; + } - this.quaternion.setFromRotationMatrix( m1 ); + if (refreshProgram || _currentCamera !== camera) { + p_uniforms.setValue(_gl, 'projectionMatrix', camera.projectionMatrix); - }; + if (capabilities.logarithmicDepthBuffer) { + p_uniforms.setValue(_gl, 'logDepthBufFC', 2.0 / (Math.log(camera.far + 1.0) / Math.LN2)); + } - }(), + if (_currentCamera !== camera) { + _currentCamera = camera; // lighting uniforms depend on the camera so enforce an update + // now, in case this material supports lights - or later, when + // the next material that does gets activated: - add: function ( object ) { + refreshMaterial = true; // set to true on material change - if ( object === this ) { + refreshLights = true; // remains set until update done + } // load material specific uniforms + // (shader material also gets them for the sake of genericity) - console.warn( 'THREE.Object3D.add: An object can\'t be added as a child of itself.' ); - return; - } + if (material.isShaderMaterial || material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap) { + var uCamPos = p_uniforms.map.cameraPosition; - if ( object instanceof THREE.Object3D ) { + if (uCamPos !== undefined) { + uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera.matrixWorld)); + } + } - if ( object.parent !== undefined ) { + if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) { + p_uniforms.setValue(_gl, 'isOrthographic', camera.isOrthographicCamera === true); + } - object.parent.remove( object ); + if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial || material.isShadowMaterial || material.skinning) { + p_uniforms.setValue(_gl, 'viewMatrix', camera.matrixWorldInverse); + } + } // skinning uniforms must be set even if material didn't change + // auto-setting of texture unit for bone texture must go before other textures + // otherwise textures used for skinning can take over texture units reserved for other material textures + + + if (material.skinning) { + p_uniforms.setOptional(_gl, object, 'bindMatrix'); + p_uniforms.setOptional(_gl, object, 'bindMatrixInverse'); + var skeleton = object.skeleton; + + if (skeleton) { + var bones = skeleton.bones; + + if (capabilities.floatVertexTextures) { + if (skeleton.boneTexture === undefined) { + // layout (1 matrix = 4 pixels) + // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4) + // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8) + // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16) + // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32) + // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64) + var size = Math.sqrt(bones.length * 4); // 4 pixels needed for 1 matrix + + size = MathUtils.ceilPowerOfTwo(size); + size = Math.max(size, 4); + var boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel + + boneMatrices.set(skeleton.boneMatrices); // copy current values + + var boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType); + skeleton.boneMatrices = boneMatrices; + skeleton.boneTexture = boneTexture; + skeleton.boneTextureSize = size; + } + p_uniforms.setValue(_gl, 'boneTexture', skeleton.boneTexture, textures); + p_uniforms.setValue(_gl, 'boneTextureSize', skeleton.boneTextureSize); + } else { + p_uniforms.setOptional(_gl, skeleton, 'boneMatrices'); + } + } } - object.parent = this; - object.dispatchEvent( { type: 'added' } ); + if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) { + materialProperties.receiveShadow = object.receiveShadow; + p_uniforms.setValue(_gl, 'receiveShadow', object.receiveShadow); + } - this.children.push( object ); + if (refreshMaterial) { + p_uniforms.setValue(_gl, 'toneMappingExposure', _this.toneMappingExposure); - // add to scene + if (materialProperties.needsLights) { + // the current material requires lighting info + // note: all lighting uniforms are always set correctly + // they simply reference the renderer's state for their + // values + // + // use the current material's .needsUpdate flags to set + // the GL state when required + markUniformsLightsNeedsUpdate(m_uniforms, refreshLights); + } // refresh uniforms common to several materials - var scene = this; - while ( scene.parent !== undefined ) { + if (fog && material.fog) { + materials.refreshFogUniforms(m_uniforms, fog); + } - scene = scene.parent; + materials.refreshMaterialUniforms(m_uniforms, material, _pixelRatio, _height); + WebGLUniforms.upload(_gl, materialProperties.uniformsList, m_uniforms, textures); + } + if (material.isShaderMaterial && material.uniformsNeedUpdate === true) { + WebGLUniforms.upload(_gl, materialProperties.uniformsList, m_uniforms, textures); + material.uniformsNeedUpdate = false; } - if ( scene !== undefined && scene instanceof THREE.Scene ) { + if (material.isSpriteMaterial) { + p_uniforms.setValue(_gl, 'center', object.center); + } // common matrices - scene.__addObject( object ); - } + p_uniforms.setValue(_gl, 'modelViewMatrix', object.modelViewMatrix); + p_uniforms.setValue(_gl, 'normalMatrix', object.normalMatrix); + p_uniforms.setValue(_gl, 'modelMatrix', object.matrixWorld); + return program; + } // If uniforms are marked as clean, they don't need to be loaded to the GPU. + + function markUniformsLightsNeedsUpdate(uniforms, value) { + uniforms.ambientLightColor.needsUpdate = value; + uniforms.lightProbe.needsUpdate = value; + uniforms.directionalLights.needsUpdate = value; + uniforms.directionalLightShadows.needsUpdate = value; + uniforms.pointLights.needsUpdate = value; + uniforms.pointLightShadows.needsUpdate = value; + uniforms.spotLights.needsUpdate = value; + uniforms.spotLightShadows.needsUpdate = value; + uniforms.rectAreaLights.needsUpdate = value; + uniforms.hemisphereLights.needsUpdate = value; } - }, + function materialNeedsLights(material) { + return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isShadowMaterial || material.isShaderMaterial && material.lights === true; + } // - remove: function ( object ) { - var index = this.children.indexOf( object ); + this.setFramebuffer = function (value) { + if (_framebuffer !== value && _currentRenderTarget === null) _gl.bindFramebuffer(36160, value); + _framebuffer = value; + }; - if ( index !== - 1 ) { + this.getActiveCubeFace = function () { + return _currentActiveCubeFace; + }; - object.parent = undefined; - object.dispatchEvent( { type: 'removed' } ); + this.getActiveMipmapLevel = function () { + return _currentActiveMipmapLevel; + }; - this.children.splice( index, 1 ); + this.getRenderList = function () { + return currentRenderList; + }; - // remove from scene + this.setRenderList = function (renderList) { + currentRenderList = renderList; + }; - var scene = this; + this.getRenderState = function () { + return currentRenderState; + }; - while ( scene.parent !== undefined ) { + this.setRenderState = function (renderState) { + currentRenderState = renderState; + }; - scene = scene.parent; + this.getRenderTarget = function () { + return _currentRenderTarget; + }; + this.setRenderTarget = function (renderTarget, activeCubeFace, activeMipmapLevel) { + if (activeCubeFace === void 0) { + activeCubeFace = 0; } - if ( scene !== undefined && scene instanceof THREE.Scene ) { + if (activeMipmapLevel === void 0) { + activeMipmapLevel = 0; + } - scene.__removeObject( object ); + _currentRenderTarget = renderTarget; + _currentActiveCubeFace = activeCubeFace; + _currentActiveMipmapLevel = activeMipmapLevel; + if (renderTarget && properties.get(renderTarget).__webglFramebuffer === undefined) { + textures.setupRenderTarget(renderTarget); } - } + var framebuffer = _framebuffer; + var isCube = false; - }, + if (renderTarget) { + var __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer; - traverse: function ( callback ) { + if (renderTarget.isWebGLCubeRenderTarget) { + framebuffer = __webglFramebuffer[activeCubeFace]; + isCube = true; + } else if (renderTarget.isWebGLMultisampleRenderTarget) { + framebuffer = properties.get(renderTarget).__webglMultisampledFramebuffer; + } else { + framebuffer = __webglFramebuffer; + } - callback( this ); + _currentViewport.copy(renderTarget.viewport); - for ( var i = 0, l = this.children.length; i < l; i ++ ) { + _currentScissor.copy(renderTarget.scissor); - this.children[ i ].traverse( callback ); + _currentScissorTest = renderTarget.scissorTest; + } else { + _currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor(); - } + _currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor(); - }, + _currentScissorTest = _scissorTest; + } - getObjectById: function ( id, recursive ) { + if (_currentFramebuffer !== framebuffer) { + _gl.bindFramebuffer(36160, framebuffer); - for ( var i = 0, l = this.children.length; i < l; i ++ ) { + _currentFramebuffer = framebuffer; + } - var child = this.children[ i ]; + state.viewport(_currentViewport); + state.scissor(_currentScissor); + state.setScissorTest(_currentScissorTest); - if ( child.id === id ) { + if (isCube) { + var textureProperties = properties.get(renderTarget.texture); - return child; + _gl.framebufferTexture2D(36160, 36064, 34069 + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel); + } + }; + this.readRenderTargetPixels = function (renderTarget, x, y, width, height, buffer, activeCubeFaceIndex) { + if (!(renderTarget && renderTarget.isWebGLRenderTarget)) { + console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.'); + return; } - if ( recursive === true ) { + var framebuffer = properties.get(renderTarget).__webglFramebuffer; - child = child.getObjectById( id, recursive ); + if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined) { + framebuffer = framebuffer[activeCubeFaceIndex]; + } - if ( child !== undefined ) { + if (framebuffer) { + var restore = false; - return child; + if (framebuffer !== _currentFramebuffer) { + _gl.bindFramebuffer(36160, framebuffer); + restore = true; } - } + try { + var texture = renderTarget.texture; + var textureFormat = texture.format; + var textureType = texture.type; - } + if (textureFormat !== RGBAFormat && utils.convert(textureFormat) !== _gl.getParameter(35739)) { + console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.'); + return; + } - return undefined; + if (textureType !== UnsignedByteType && utils.convert(textureType) !== _gl.getParameter(35738) && // IE11, Edge and Chrome Mac < 52 (#9513) + !(textureType === FloatType && (capabilities.isWebGL2 || extensions.get('OES_texture_float') || extensions.get('WEBGL_color_buffer_float'))) && // Chrome Mac >= 52 and Firefox + !(textureType === HalfFloatType && (capabilities.isWebGL2 ? extensions.get('EXT_color_buffer_float') : extensions.get('EXT_color_buffer_half_float')))) { + console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.'); + return; + } - }, + if (_gl.checkFramebufferStatus(36160) === 36053) { + // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604) + if (x >= 0 && x <= renderTarget.width - width && y >= 0 && y <= renderTarget.height - height) { + _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), buffer); + } + } else { + console.error('THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.'); + } + } finally { + if (restore) { + _gl.bindFramebuffer(36160, _currentFramebuffer); + } + } + } + }; - getObjectByName: function ( name, recursive ) { + this.copyFramebufferToTexture = function (position, texture, level) { + if (level === undefined) level = 0; + var levelScale = Math.pow(2, -level); + var width = Math.floor(texture.image.width * levelScale); + var height = Math.floor(texture.image.height * levelScale); + var glFormat = utils.convert(texture.format); + textures.setTexture2D(texture, 0); - for ( var i = 0, l = this.children.length; i < l; i ++ ) { + _gl.copyTexImage2D(3553, level, glFormat, position.x, position.y, width, height, 0); - var child = this.children[ i ]; + state.unbindTexture(); + }; - if ( child.name === name ) { + this.copyTextureToTexture = function (position, srcTexture, dstTexture, level) { + if (level === undefined) level = 0; + var width = srcTexture.image.width; + var height = srcTexture.image.height; + var glFormat = utils.convert(dstTexture.format); + var glType = utils.convert(dstTexture.type); + textures.setTexture2D(dstTexture, 0); // As another texture upload may have changed pixelStorei + // parameters, make sure they are correct for the dstTexture - return child; + _gl.pixelStorei(37440, dstTexture.flipY); - } + _gl.pixelStorei(37441, dstTexture.premultiplyAlpha); - if ( recursive === true ) { + _gl.pixelStorei(3317, dstTexture.unpackAlignment); - child = child.getObjectByName( name, recursive ); + if (srcTexture.isDataTexture) { + _gl.texSubImage2D(3553, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data); + } else { + if (srcTexture.isCompressedTexture) { + _gl.compressedTexSubImage2D(3553, level, position.x, position.y, srcTexture.mipmaps[0].width, srcTexture.mipmaps[0].height, glFormat, srcTexture.mipmaps[0].data); + } else { + _gl.texSubImage2D(3553, level, position.x, position.y, glFormat, glType, srcTexture.image); + } + } // Generate mipmaps only when copying level 0 - if ( child !== undefined ) { - return child; + if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(3553); + state.unbindTexture(); + }; - } + this.initTexture = function (texture) { + textures.setTexture2D(texture, 0); + state.unbindTexture(); + }; - } + if (typeof __THREE_DEVTOOLS__ !== 'undefined') { + __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { + detail: this + })); // eslint-disable-line no-undef } + } - return undefined; + function WebGL1Renderer(parameters) { + WebGLRenderer.call(this, parameters); + } - }, + WebGL1Renderer.prototype = Object.assign(Object.create(WebGLRenderer.prototype), { + constructor: WebGL1Renderer, + isWebGL1Renderer: true + }); - getChildByName: function ( name, recursive ) { + var FogExp2 = /*#__PURE__*/function () { + function FogExp2(color, density) { + Object.defineProperty(this, 'isFogExp2', { + value: true + }); + this.name = ''; + this.color = new Color(color); + this.density = density !== undefined ? density : 0.00025; + } - console.warn( 'DEPRECATED: Object3D\'s .getChildByName() has been renamed to .getObjectByName().' ); - return this.getObjectByName( name, recursive ); + var _proto = FogExp2.prototype; - }, + _proto.clone = function clone() { + return new FogExp2(this.color, this.density); + }; - getDescendants: function ( array ) { - - if ( array === undefined ) array = []; - - Array.prototype.push.apply( array, this.children ); - - for ( var i = 0, l = this.children.length; i < l; i ++ ) { + _proto.toJSON = function toJSON() + /* meta */ + { + return { + type: 'FogExp2', + color: this.color.getHex(), + density: this.density + }; + }; - this.children[ i ].getDescendants( array ); + return FogExp2; + }(); + var Fog = /*#__PURE__*/function () { + function Fog(color, near, far) { + Object.defineProperty(this, 'isFog', { + value: true + }); + this.name = ''; + this.color = new Color(color); + this.near = near !== undefined ? near : 1; + this.far = far !== undefined ? far : 1000; } - return array; + var _proto = Fog.prototype; - }, + _proto.clone = function clone() { + return new Fog(this.color, this.near, this.far); + }; - updateMatrix: function () { + _proto.toJSON = function toJSON() + /* meta */ + { + return { + type: 'Fog', + color: this.color.getHex(), + near: this.near, + far: this.far + }; + }; - this.matrix.compose( this.position, this.quaternion, this.scale ); + return Fog; + }(); - this.matrixWorldNeedsUpdate = true; + var Scene = /*#__PURE__*/function (_Object3D) { + _inheritsLoose(Scene, _Object3D); - }, + function Scene() { + var _this; - updateMatrixWorld: function ( force ) { + _this = _Object3D.call(this) || this; + Object.defineProperty(_assertThisInitialized(_this), 'isScene', { + value: true + }); + _this.type = 'Scene'; + _this.background = null; + _this.environment = null; + _this.fog = null; + _this.overrideMaterial = null; + _this.autoUpdate = true; // checked by the renderer - if ( this.matrixAutoUpdate === true ) this.updateMatrix(); + if (typeof __THREE_DEVTOOLS__ !== 'undefined') { + __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', { + detail: _assertThisInitialized(_this) + })); // eslint-disable-line no-undef - if ( this.matrixWorldNeedsUpdate === true || force === true ) { + } - if ( this.parent === undefined ) { + return _this; + } - this.matrixWorld.copy( this.matrix ); + var _proto = Scene.prototype; - } else { + _proto.copy = function copy(source, recursive) { + _Object3D.prototype.copy.call(this, source, recursive); - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); + if (source.background !== null) this.background = source.background.clone(); + if (source.environment !== null) this.environment = source.environment.clone(); + if (source.fog !== null) this.fog = source.fog.clone(); + if (source.overrideMaterial !== null) this.overrideMaterial = source.overrideMaterial.clone(); + this.autoUpdate = source.autoUpdate; + this.matrixAutoUpdate = source.matrixAutoUpdate; + return this; + }; - } + _proto.toJSON = function toJSON(meta) { + var data = _Object3D.prototype.toJSON.call(this, meta); - this.matrixWorldNeedsUpdate = false; + if (this.background !== null) data.object.background = this.background.toJSON(meta); + if (this.environment !== null) data.object.environment = this.environment.toJSON(meta); + if (this.fog !== null) data.object.fog = this.fog.toJSON(); + return data; + }; - force = true; + return Scene; + }(Object3D); + + function InterleavedBuffer(array, stride) { + this.array = array; + this.stride = stride; + this.count = array !== undefined ? array.length / stride : 0; + this.usage = StaticDrawUsage; + this.updateRange = { + offset: 0, + count: -1 + }; + this.version = 0; + this.uuid = MathUtils.generateUUID(); + } + Object.defineProperty(InterleavedBuffer.prototype, 'needsUpdate', { + set: function set(value) { + if (value === true) this.version++; } + }); + Object.assign(InterleavedBuffer.prototype, { + isInterleavedBuffer: true, + onUploadCallback: function onUploadCallback() {}, + setUsage: function setUsage(value) { + this.usage = value; + return this; + }, + copy: function copy(source) { + this.array = new source.array.constructor(source.array); + this.count = source.count; + this.stride = source.stride; + this.usage = source.usage; + return this; + }, + copyAt: function copyAt(index1, attribute, index2) { + index1 *= this.stride; + index2 *= attribute.stride; - // update children - - for ( var i = 0, l = this.children.length; i < l; i ++ ) { + for (var i = 0, l = this.stride; i < l; i++) { + this.array[index1 + i] = attribute.array[index2 + i]; + } - this.children[ i ].updateMatrixWorld( force ); + return this; + }, + set: function set(value, offset) { + if (offset === undefined) offset = 0; + this.array.set(value, offset); + return this; + }, + clone: function clone(data) { + if (data.arrayBuffers === undefined) { + data.arrayBuffers = {}; + } - } + if (this.array.buffer._uuid === undefined) { + this.array.buffer._uuid = MathUtils.generateUUID(); + } - }, + if (data.arrayBuffers[this.array.buffer._uuid] === undefined) { + data.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer; + } - clone: function ( object, recursive ) { + var array = new this.array.constructor(data.arrayBuffers[this.array.buffer._uuid]); + var ib = new InterleavedBuffer(array, this.stride); + ib.setUsage(this.usage); + return ib; + }, + onUpload: function onUpload(callback) { + this.onUploadCallback = callback; + return this; + }, + toJSON: function toJSON(data) { + if (data.arrayBuffers === undefined) { + data.arrayBuffers = {}; + } // generate UUID for array buffer if necessary - if ( object === undefined ) object = new THREE.Object3D(); - if ( recursive === undefined ) recursive = true; - object.name = this.name; + if (this.array.buffer._uuid === undefined) { + this.array.buffer._uuid = MathUtils.generateUUID(); + } - object.up.copy( this.up ); + if (data.arrayBuffers[this.array.buffer._uuid] === undefined) { + data.arrayBuffers[this.array.buffer._uuid] = Array.prototype.slice.call(new Uint32Array(this.array.buffer)); + } // - object.position.copy( this.position ); - object.quaternion.copy( this.quaternion ); - object.scale.copy( this.scale ); - object.renderDepth = this.renderDepth; + return { + uuid: this.uuid, + buffer: this.array.buffer._uuid, + type: this.array.constructor.name, + stride: this.stride + }; + } + }); - object.rotationAutoUpdate = this.rotationAutoUpdate; + var _vector$6 = new Vector3(); - object.matrix.copy( this.matrix ); - object.matrixWorld.copy( this.matrixWorld ); + function InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, normalized) { + this.name = ''; + this.data = interleavedBuffer; + this.itemSize = itemSize; + this.offset = offset; + this.normalized = normalized === true; + } - object.matrixAutoUpdate = this.matrixAutoUpdate; - object.matrixWorldNeedsUpdate = this.matrixWorldNeedsUpdate; + Object.defineProperties(InterleavedBufferAttribute.prototype, { + count: { + get: function get() { + return this.data.count; + } + }, + array: { + get: function get() { + return this.data.array; + } + }, + needsUpdate: { + set: function set(value) { + this.data.needsUpdate = value; + } + } + }); + Object.assign(InterleavedBufferAttribute.prototype, { + isInterleavedBufferAttribute: true, + applyMatrix4: function applyMatrix4(m) { + for (var i = 0, l = this.data.count; i < l; i++) { + _vector$6.x = this.getX(i); + _vector$6.y = this.getY(i); + _vector$6.z = this.getZ(i); - object.visible = this.visible; + _vector$6.applyMatrix4(m); - object.castShadow = this.castShadow; - object.receiveShadow = this.receiveShadow; + this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); + } - object.frustumCulled = this.frustumCulled; + return this; + }, + setX: function setX(index, x) { + this.data.array[index * this.data.stride + this.offset] = x; + return this; + }, + setY: function setY(index, y) { + this.data.array[index * this.data.stride + this.offset + 1] = y; + return this; + }, + setZ: function setZ(index, z) { + this.data.array[index * this.data.stride + this.offset + 2] = z; + return this; + }, + setW: function setW(index, w) { + this.data.array[index * this.data.stride + this.offset + 3] = w; + return this; + }, + getX: function getX(index) { + return this.data.array[index * this.data.stride + this.offset]; + }, + getY: function getY(index) { + return this.data.array[index * this.data.stride + this.offset + 1]; + }, + getZ: function getZ(index) { + return this.data.array[index * this.data.stride + this.offset + 2]; + }, + getW: function getW(index) { + return this.data.array[index * this.data.stride + this.offset + 3]; + }, + setXY: function setXY(index, x, y) { + index = index * this.data.stride + this.offset; + this.data.array[index + 0] = x; + this.data.array[index + 1] = y; + return this; + }, + setXYZ: function setXYZ(index, x, y, z) { + index = index * this.data.stride + this.offset; + this.data.array[index + 0] = x; + this.data.array[index + 1] = y; + this.data.array[index + 2] = z; + return this; + }, + setXYZW: function setXYZW(index, x, y, z, w) { + index = index * this.data.stride + this.offset; + this.data.array[index + 0] = x; + this.data.array[index + 1] = y; + this.data.array[index + 2] = z; + this.data.array[index + 3] = w; + return this; + }, + clone: function clone(data) { + if (data === undefined) { + console.log('THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data.'); + var array = []; - object.userData = JSON.parse( JSON.stringify( this.userData ) ); + for (var i = 0; i < this.count; i++) { + var index = i * this.data.stride + this.offset; - if ( recursive === true ) { + for (var j = 0; j < this.itemSize; j++) { + array.push(this.data.array[index + j]); + } + } - for ( var i = 0; i < this.children.length; i ++ ) { + return new BufferAttribute(new this.array.constructor(array), this.itemSize, this.normalized); + } else { + if (data.interleavedBuffers === undefined) { + data.interleavedBuffers = {}; + } - var child = this.children[ i ]; - object.add( child.clone() ); + if (data.interleavedBuffers[this.data.uuid] === undefined) { + data.interleavedBuffers[this.data.uuid] = this.data.clone(data); + } + return new InterleavedBufferAttribute(data.interleavedBuffers[this.data.uuid], this.itemSize, this.offset, this.normalized); } + }, + toJSON: function toJSON(data) { + if (data === undefined) { + console.log('THREE.InterleavedBufferAttribute.toJSON(): Serializing an interlaved buffer attribute will deinterleave buffer data.'); + var array = []; - } - - return object; - - } - -}; + for (var i = 0; i < this.count; i++) { + var index = i * this.data.stride + this.offset; -THREE.EventDispatcher.prototype.apply( THREE.Object3D.prototype ); + for (var j = 0; j < this.itemSize; j++) { + array.push(this.data.array[index + j]); + } + } // deinterleave data and save it as an ordinary buffer attribute for now -THREE.Object3DIdCount = 0; -/** - * @author mrdoob / http://mrdoob.com/ - * @author supereggbert / http://www.paulbrunt.co.uk/ - * @author julianwa / https://github.com/julianwa - */ + return { + itemSize: this.itemSize, + type: this.array.constructor.name, + array: array, + normalized: this.normalized + }; + } else { + // save as true interlaved attribtue + if (data.interleavedBuffers === undefined) { + data.interleavedBuffers = {}; + } -THREE.Projector = function () { + if (data.interleavedBuffers[this.data.uuid] === undefined) { + data.interleavedBuffers[this.data.uuid] = this.data.toJSON(data); + } - var _object, _objectCount, _objectPool = [], _objectPoolLength = 0, - _vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0, - _face, _faceCount, _facePool = [], _facePoolLength = 0, - _line, _lineCount, _linePool = [], _linePoolLength = 0, - _sprite, _spriteCount, _spritePool = [], _spritePoolLength = 0, + return { + isInterleavedBufferAttribute: true, + itemSize: this.itemSize, + data: this.data.uuid, + offset: this.offset, + normalized: this.normalized + }; + } + } + }); - _renderData = { objects: [], lights: [], elements: [] }, + /** + * parameters = { + * color: , + * map: new THREE.Texture( ), + * alphaMap: new THREE.Texture( ), + * rotation: , + * sizeAttenuation: + * } + */ - _vA = new THREE.Vector3(), - _vB = new THREE.Vector3(), - _vC = new THREE.Vector3(), + function SpriteMaterial(parameters) { + Material.call(this); + this.type = 'SpriteMaterial'; + this.color = new Color(0xffffff); + this.map = null; + this.alphaMap = null; + this.rotation = 0; + this.sizeAttenuation = true; + this.transparent = true; + this.setValues(parameters); + } + + SpriteMaterial.prototype = Object.create(Material.prototype); + SpriteMaterial.prototype.constructor = SpriteMaterial; + SpriteMaterial.prototype.isSpriteMaterial = true; + + SpriteMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.color.copy(source.color); + this.map = source.map; + this.alphaMap = source.alphaMap; + this.rotation = source.rotation; + this.sizeAttenuation = source.sizeAttenuation; + return this; + }; - _vector3 = new THREE.Vector3(), - _vector4 = new THREE.Vector4(), + var _geometry; - _clipBox = new THREE.Box3( new THREE.Vector3( -1, -1, -1 ), new THREE.Vector3( 1, 1, 1 ) ), - _boundingBox = new THREE.Box3(), - _points3 = new Array( 3 ), - _points4 = new Array( 4 ), + var _intersectPoint = new Vector3(); - _viewMatrix = new THREE.Matrix4(), - _viewProjectionMatrix = new THREE.Matrix4(), + var _worldScale = new Vector3(); - _modelMatrix, - _modelViewProjectionMatrix = new THREE.Matrix4(), + var _mvPosition = new Vector3(); - _normalMatrix = new THREE.Matrix3(), + var _alignedPosition = new Vector2(); - _frustum = new THREE.Frustum(), + var _rotatedPosition = new Vector2(); - _clippedVertex1PositionScreen = new THREE.Vector4(), - _clippedVertex2PositionScreen = new THREE.Vector4(); + var _viewWorldMatrix = new Matrix4(); - this.projectVector = function ( vector, camera ) { + var _vA$1 = new Vector3(); - camera.matrixWorldInverse.getInverse( camera.matrixWorld ); + var _vB$1 = new Vector3(); - _viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); + var _vC$1 = new Vector3(); - return vector.applyProjection( _viewProjectionMatrix ); + var _uvA$1 = new Vector2(); - }; + var _uvB$1 = new Vector2(); - this.unprojectVector = function () { + var _uvC$1 = new Vector2(); - var projectionMatrixInverse = new THREE.Matrix4(); + function Sprite(material) { + Object3D.call(this); + this.type = 'Sprite'; - return function ( vector, camera ) { + if (_geometry === undefined) { + _geometry = new BufferGeometry(); + var float32Array = new Float32Array([-0.5, -0.5, 0, 0, 0, 0.5, -0.5, 0, 1, 0, 0.5, 0.5, 0, 1, 1, -0.5, 0.5, 0, 0, 1]); + var interleavedBuffer = new InterleavedBuffer(float32Array, 5); - projectionMatrixInverse.getInverse( camera.projectionMatrix ); - _viewProjectionMatrix.multiplyMatrices( camera.matrixWorld, projectionMatrixInverse ); + _geometry.setIndex([0, 1, 2, 0, 2, 3]); - return vector.applyProjection( _viewProjectionMatrix ); + _geometry.setAttribute('position', new InterleavedBufferAttribute(interleavedBuffer, 3, 0, false)); - }; + _geometry.setAttribute('uv', new InterleavedBufferAttribute(interleavedBuffer, 2, 3, false)); + } - }(); + this.geometry = _geometry; + this.material = material !== undefined ? material : new SpriteMaterial(); + this.center = new Vector2(0.5, 0.5); + } - this.pickingRay = function ( vector, camera ) { + Sprite.prototype = Object.assign(Object.create(Object3D.prototype), { + constructor: Sprite, + isSprite: true, + raycast: function raycast(raycaster, intersects) { + if (raycaster.camera === null) { + console.error('THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.'); + } - // set two vectors with opposing z values - vector.z = -1.0; - var end = new THREE.Vector3( vector.x, vector.y, 1.0 ); + _worldScale.setFromMatrixScale(this.matrixWorld); - this.unprojectVector( vector, camera ); - this.unprojectVector( end, camera ); + _viewWorldMatrix.copy(raycaster.camera.matrixWorld); - // find direction from vector to end - end.sub( vector ).normalize(); + this.modelViewMatrix.multiplyMatrices(raycaster.camera.matrixWorldInverse, this.matrixWorld); - return new THREE.Raycaster( vector, end ); + _mvPosition.setFromMatrixPosition(this.modelViewMatrix); - }; + if (raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false) { + _worldScale.multiplyScalar(-_mvPosition.z); + } - var projectObject = function ( object ) { + var rotation = this.material.rotation; + var sin, cos; - if ( object.visible === false ) return; + if (rotation !== 0) { + cos = Math.cos(rotation); + sin = Math.sin(rotation); + } - if ( object instanceof THREE.Light ) { + var center = this.center; + transformVertex(_vA$1.set(-0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos); + transformVertex(_vB$1.set(0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos); + transformVertex(_vC$1.set(0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos); - _renderData.lights.push( object ); + _uvA$1.set(0, 0); - } else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Sprite ) { + _uvB$1.set(1, 0); - if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) { + _uvC$1.set(1, 1); // check first triangle - _object = getNextObjectInPool(); - _object.id = object.id; - _object.object = object; - if ( object.renderDepth !== null ) { + var intersect = raycaster.ray.intersectTriangle(_vA$1, _vB$1, _vC$1, false, _intersectPoint); - _object.z = object.renderDepth; + if (intersect === null) { + // check second triangle + transformVertex(_vB$1.set(-0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos); - } else { + _uvB$1.set(0, 1); - _vector3.setFromMatrixPosition( object.matrixWorld ); - _vector3.applyProjection( _viewProjectionMatrix ); - _object.z = _vector3.z; + intersect = raycaster.ray.intersectTriangle(_vA$1, _vC$1, _vB$1, false, _intersectPoint); + if (intersect === null) { + return; } - - _renderData.objects.push( _object ); - } + var distance = raycaster.ray.origin.distanceTo(_intersectPoint); + if (distance < raycaster.near || distance > raycaster.far) return; + intersects.push({ + distance: distance, + point: _intersectPoint.clone(), + uv: Triangle.getUV(_intersectPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2()), + face: null, + object: this + }); + }, + copy: function copy(source) { + Object3D.prototype.copy.call(this, source); + if (source.center !== undefined) this.center.copy(source.center); + this.material = source.material; + return this; } + }); - for ( var i = 0, l = object.children.length; i < l; i ++ ) { + function transformVertex(vertexPosition, mvPosition, center, scale, sin, cos) { + // compute position in camera space + _alignedPosition.subVectors(vertexPosition, center).addScalar(0.5).multiply(scale); // to check if rotation is not zero - projectObject( object.children[ i ] ); + if (sin !== undefined) { + _rotatedPosition.x = cos * _alignedPosition.x - sin * _alignedPosition.y; + _rotatedPosition.y = sin * _alignedPosition.x + cos * _alignedPosition.y; + } else { + _rotatedPosition.copy(_alignedPosition); } - }; + vertexPosition.copy(mvPosition); + vertexPosition.x += _rotatedPosition.x; + vertexPosition.y += _rotatedPosition.y; // transform to world space - var projectGraph = function ( root, sortObjects ) { + vertexPosition.applyMatrix4(_viewWorldMatrix); + } - _objectCount = 0; + var _v1$4 = new Vector3(); - _renderData.objects.length = 0; - _renderData.lights.length = 0; + var _v2$2 = new Vector3(); - projectObject( root ); + function LOD() { + Object3D.call(this); + this._currentLevel = 0; + this.type = 'LOD'; + Object.defineProperties(this, { + levels: { + enumerable: true, + value: [] + } + }); + this.autoUpdate = true; + } - if ( sortObjects === true ) { + LOD.prototype = Object.assign(Object.create(Object3D.prototype), { + constructor: LOD, + isLOD: true, + copy: function copy(source) { + Object3D.prototype.copy.call(this, source, false); + var levels = source.levels; - _renderData.objects.sort( painterSort ); + for (var i = 0, l = levels.length; i < l; i++) { + var level = levels[i]; + this.addLevel(level.object.clone(), level.distance); + } - } + this.autoUpdate = source.autoUpdate; + return this; + }, + addLevel: function addLevel(object, distance) { + if (distance === undefined) distance = 0; + distance = Math.abs(distance); + var levels = this.levels; + var l; + + for (l = 0; l < levels.length; l++) { + if (distance < levels[l].distance) { + break; + } + } - }; + levels.splice(l, 0, { + distance: distance, + object: object + }); + this.add(object); + return this; + }, + getCurrentLevel: function getCurrentLevel() { + return this._currentLevel; + }, + getObjectForDistance: function getObjectForDistance(distance) { + var levels = this.levels; - var RenderList = function () { + if (levels.length > 0) { + var i, l; - var normals = []; - var uvs = []; + for (i = 1, l = levels.length; i < l; i++) { + if (distance < levels[i].distance) { + break; + } + } - var object = null; - var material = null; + return levels[i - 1].object; + } - var normalMatrix = new THREE.Matrix3(); + return null; + }, + raycast: function raycast(raycaster, intersects) { + var levels = this.levels; - var setObject = function ( value ) { + if (levels.length > 0) { + _v1$4.setFromMatrixPosition(this.matrixWorld); - object = value; - material = object.material; + var distance = raycaster.ray.origin.distanceTo(_v1$4); + this.getObjectForDistance(distance).raycast(raycaster, intersects); + } + }, + update: function update(camera) { + var levels = this.levels; - normalMatrix.getNormalMatrix( object.matrixWorld ); + if (levels.length > 1) { + _v1$4.setFromMatrixPosition(camera.matrixWorld); - normals.length = 0; - uvs.length = 0; + _v2$2.setFromMatrixPosition(this.matrixWorld); - }; + var distance = _v1$4.distanceTo(_v2$2) / camera.zoom; + levels[0].object.visible = true; + var i, l; - var projectVertex = function ( vertex ) { + for (i = 1, l = levels.length; i < l; i++) { + if (distance >= levels[i].distance) { + levels[i - 1].object.visible = false; + levels[i].object.visible = true; + } else { + break; + } + } - var position = vertex.position; - var positionWorld = vertex.positionWorld; - var positionScreen = vertex.positionScreen; + this._currentLevel = i - 1; - positionWorld.copy( position ).applyMatrix4( _modelMatrix ); - positionScreen.copy( positionWorld ).applyMatrix4( _viewProjectionMatrix ); + for (; i < l; i++) { + levels[i].object.visible = false; + } + } + }, + toJSON: function toJSON(meta) { + var data = Object3D.prototype.toJSON.call(this, meta); + if (this.autoUpdate === false) data.object.autoUpdate = false; + data.object.levels = []; + var levels = this.levels; - var invW = 1 / positionScreen.w; + for (var i = 0, l = levels.length; i < l; i++) { + var level = levels[i]; + data.object.levels.push({ + object: level.object.uuid, + distance: level.distance + }); + } - positionScreen.x *= invW; - positionScreen.y *= invW; - positionScreen.z *= invW; + return data; + } + }); - vertex.visible = positionScreen.x >= -1 && positionScreen.x <= 1 && - positionScreen.y >= -1 && positionScreen.y <= 1 && - positionScreen.z >= -1 && positionScreen.z <= 1; + function SkinnedMesh(geometry, material) { + if (geometry && geometry.isGeometry) { + console.error('THREE.SkinnedMesh no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.'); + } - }; + Mesh.call(this, geometry, material); + this.type = 'SkinnedMesh'; + this.bindMode = 'attached'; + this.bindMatrix = new Matrix4(); + this.bindMatrixInverse = new Matrix4(); + } - var pushVertex = function ( x, y, z ) { + SkinnedMesh.prototype = Object.assign(Object.create(Mesh.prototype), { + constructor: SkinnedMesh, + isSkinnedMesh: true, + copy: function copy(source) { + Mesh.prototype.copy.call(this, source); + this.bindMode = source.bindMode; + this.bindMatrix.copy(source.bindMatrix); + this.bindMatrixInverse.copy(source.bindMatrixInverse); + this.skeleton = source.skeleton; + return this; + }, + bind: function bind(skeleton, bindMatrix) { + this.skeleton = skeleton; - _vertex = getNextVertexInPool(); - _vertex.position.set( x, y, z ); + if (bindMatrix === undefined) { + this.updateMatrixWorld(true); + this.skeleton.calculateInverses(); + bindMatrix = this.matrixWorld; + } - projectVertex( _vertex ); + this.bindMatrix.copy(bindMatrix); + this.bindMatrixInverse.getInverse(bindMatrix); + }, + pose: function pose() { + this.skeleton.pose(); + }, + normalizeSkinWeights: function normalizeSkinWeights() { + var vector = new Vector4(); + var skinWeight = this.geometry.attributes.skinWeight; + + for (var i = 0, l = skinWeight.count; i < l; i++) { + vector.x = skinWeight.getX(i); + vector.y = skinWeight.getY(i); + vector.z = skinWeight.getZ(i); + vector.w = skinWeight.getW(i); + var scale = 1.0 / vector.manhattanLength(); + + if (scale !== Infinity) { + vector.multiplyScalar(scale); + } else { + vector.set(1, 0, 0, 0); // do something reasonable + } - }; + skinWeight.setXYZW(i, vector.x, vector.y, vector.z, vector.w); + } + }, + updateMatrixWorld: function updateMatrixWorld(force) { + Mesh.prototype.updateMatrixWorld.call(this, force); - var pushNormal = function ( x, y, z ) { + if (this.bindMode === 'attached') { + this.bindMatrixInverse.getInverse(this.matrixWorld); + } else if (this.bindMode === 'detached') { + this.bindMatrixInverse.getInverse(this.bindMatrix); + } else { + console.warn('THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode); + } + }, + boneTransform: function () { + var basePosition = new Vector3(); + var skinIndex = new Vector4(); + var skinWeight = new Vector4(); + var vector = new Vector3(); + var matrix = new Matrix4(); + return function (index, target) { + var skeleton = this.skeleton; + var geometry = this.geometry; + skinIndex.fromBufferAttribute(geometry.attributes.skinIndex, index); + skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index); + basePosition.fromBufferAttribute(geometry.attributes.position, index).applyMatrix4(this.bindMatrix); + target.set(0, 0, 0); + + for (var i = 0; i < 4; i++) { + var weight = skinWeight.getComponent(i); + + if (weight !== 0) { + var boneIndex = skinIndex.getComponent(i); + matrix.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]); + target.addScaledVector(vector.copy(basePosition).applyMatrix4(matrix), weight); + } + } - normals.push( x, y, z ); + return target.applyMatrix4(this.bindMatrixInverse); + }; + }() + }); - }; + var _offsetMatrix = new Matrix4(); - var pushUv = function ( x, y ) { + var _identityMatrix = new Matrix4(); - uvs.push( x, y ); + function Skeleton(bones, boneInverses) { + // copy the bone array + bones = bones || []; + this.bones = bones.slice(0); + this.boneMatrices = new Float32Array(this.bones.length * 16); + this.frame = -1; // use the supplied bone inverses or calculate the inverses - }; + if (boneInverses === undefined) { + this.calculateInverses(); + } else { + if (this.bones.length === boneInverses.length) { + this.boneInverses = boneInverses.slice(0); + } else { + console.warn('THREE.Skeleton boneInverses is the wrong length.'); + this.boneInverses = []; - var checkTriangleVisibility = function ( v1, v2, v3 ) { + for (var i = 0, il = this.bones.length; i < il; i++) { + this.boneInverses.push(new Matrix4()); + } + } + } + } - if ( v1.visible === true || v2.visible === true || v3.visible === true ) return true; + Object.assign(Skeleton.prototype, { + calculateInverses: function calculateInverses() { + this.boneInverses = []; - _points3[ 0 ] = v1.positionScreen; - _points3[ 1 ] = v2.positionScreen; - _points3[ 2 ] = v3.positionScreen; + for (var i = 0, il = this.bones.length; i < il; i++) { + var inverse = new Matrix4(); - return _clipBox.isIntersectionBox( _boundingBox.setFromPoints( _points3 ) ); + if (this.bones[i]) { + inverse.getInverse(this.bones[i].matrixWorld); + } - }; + this.boneInverses.push(inverse); + } + }, + pose: function pose() { + // recover the bind-time world matrices + for (var i = 0, il = this.bones.length; i < il; i++) { + var bone = this.bones[i]; - var checkBackfaceCulling = function ( v1, v2, v3 ) { + if (bone) { + bone.matrixWorld.getInverse(this.boneInverses[i]); + } + } // compute the local matrices, positions, rotations and scales - return ( ( v3.positionScreen.x - v1.positionScreen.x ) * - ( v2.positionScreen.y - v1.positionScreen.y ) - - ( v3.positionScreen.y - v1.positionScreen.y ) * - ( v2.positionScreen.x - v1.positionScreen.x ) ) < 0; - }; + for (var _i = 0, _il = this.bones.length; _i < _il; _i++) { + var _bone = this.bones[_i]; - var pushLine = function ( a, b ) { + if (_bone) { + if (_bone.parent && _bone.parent.isBone) { + _bone.matrix.getInverse(_bone.parent.matrixWorld); - var v1 = _vertexPool[ a ]; - var v2 = _vertexPool[ b ]; + _bone.matrix.multiply(_bone.matrixWorld); + } else { + _bone.matrix.copy(_bone.matrixWorld); + } - _line = getNextLineInPool(); + _bone.matrix.decompose(_bone.position, _bone.quaternion, _bone.scale); + } + } + }, + update: function update() { + var bones = this.bones; + var boneInverses = this.boneInverses; + var boneMatrices = this.boneMatrices; + var boneTexture = this.boneTexture; // flatten bone matrices to array - _line.id = object.id; - _line.v1.copy( v1 ); - _line.v2.copy( v2 ); - _line.z = ( v1.positionScreen.z + v2.positionScreen.z ) / 2; + for (var i = 0, il = bones.length; i < il; i++) { + // compute the offset between the current and the original transform + var matrix = bones[i] ? bones[i].matrixWorld : _identityMatrix; - _line.material = object.material; + _offsetMatrix.multiplyMatrices(matrix, boneInverses[i]); - _renderData.elements.push( _line ); + _offsetMatrix.toArray(boneMatrices, i * 16); + } - }; + if (boneTexture !== undefined) { + boneTexture.needsUpdate = true; + } + }, + clone: function clone() { + return new Skeleton(this.bones, this.boneInverses); + }, + getBoneByName: function getBoneByName(name) { + for (var i = 0, il = this.bones.length; i < il; i++) { + var bone = this.bones[i]; - var pushTriangle = function ( a, b, c ) { + if (bone.name === name) { + return bone; + } + } - var v1 = _vertexPool[ a ]; - var v2 = _vertexPool[ b ]; - var v3 = _vertexPool[ c ]; + return undefined; + }, + dispose: function dispose() { + if (this.boneTexture) { + this.boneTexture.dispose(); + this.boneTexture = undefined; + } + } + }); - if ( checkTriangleVisibility( v1, v2, v3 ) === false ) return; + function Bone() { + Object3D.call(this); + this.type = 'Bone'; + } - if ( material.side === THREE.DoubleSide || checkBackfaceCulling( v1, v2, v3 ) === true ) { + Bone.prototype = Object.assign(Object.create(Object3D.prototype), { + constructor: Bone, + isBone: true + }); - _face = getNextFaceInPool(); + var _instanceLocalMatrix = new Matrix4(); - _face.id = object.id; - _face.v1.copy( v1 ); - _face.v2.copy( v2 ); - _face.v3.copy( v3 ); - _face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3; + var _instanceWorldMatrix = new Matrix4(); - for ( var i = 0; i < 3; i ++ ) { + var _instanceIntersects = []; - var offset = arguments[ i ] * 3; - var normal = _face.vertexNormalsModel[ i ]; + var _mesh = new Mesh(); - normal.set( normals[ offset ], normals[ offset + 1 ], normals[ offset + 2 ] ); - normal.applyMatrix3( normalMatrix ).normalize(); + function InstancedMesh(geometry, material, count) { + Mesh.call(this, geometry, material); + this.instanceMatrix = new BufferAttribute(new Float32Array(count * 16), 16); + this.instanceColor = null; + this.count = count; + this.frustumCulled = false; + } - var offset2 = arguments[ i ] * 2; + InstancedMesh.prototype = Object.assign(Object.create(Mesh.prototype), { + constructor: InstancedMesh, + isInstancedMesh: true, + copy: function copy(source) { + Mesh.prototype.copy.call(this, source); + this.instanceMatrix.copy(source.instanceMatrix); + this.count = source.count; + return this; + }, + setColorAt: function setColorAt(index, color) { + if (this.instanceColor === null) { + this.instanceColor = new BufferAttribute(new Float32Array(this.count * 3), 3); + } - var uv = _face.uvs[ i ]; - uv.set( uvs[ offset2 ], uvs[ offset2 + 1 ] ); + color.toArray(this.instanceColor.array, index * 3); + }, + getMatrixAt: function getMatrixAt(index, matrix) { + matrix.fromArray(this.instanceMatrix.array, index * 16); + }, + raycast: function raycast(raycaster, intersects) { + var matrixWorld = this.matrixWorld; + var raycastTimes = this.count; + _mesh.geometry = this.geometry; + _mesh.material = this.material; + if (_mesh.material === undefined) return; - } + for (var instanceId = 0; instanceId < raycastTimes; instanceId++) { + // calculate the world matrix for each instance + this.getMatrixAt(instanceId, _instanceLocalMatrix); - _face.vertexNormalsLength = 3; + _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); // the mesh represents this single instance - _face.material = object.material; - _renderData.elements.push( _face ); + _mesh.matrixWorld = _instanceWorldMatrix; - } + _mesh.raycast(raycaster, _instanceIntersects); // process the result of raycast - }; - return { - setObject: setObject, - projectVertex: projectVertex, - checkTriangleVisibility: checkTriangleVisibility, - checkBackfaceCulling: checkBackfaceCulling, - pushVertex: pushVertex, - pushNormal: pushNormal, - pushUv: pushUv, - pushLine: pushLine, - pushTriangle: pushTriangle - } + for (var i = 0, l = _instanceIntersects.length; i < l; i++) { + var intersect = _instanceIntersects[i]; + intersect.instanceId = instanceId; + intersect.object = this; + intersects.push(intersect); + } - }; + _instanceIntersects.length = 0; + } + }, + setMatrixAt: function setMatrixAt(index, matrix) { + matrix.toArray(this.instanceMatrix.array, index * 16); + }, + updateMorphTargets: function updateMorphTargets() {} + }); - var renderList = new RenderList(); + /** + * parameters = { + * color: , + * opacity: , + * + * linewidth: , + * linecap: "round", + * linejoin: "round" + * } + */ - this.projectScene = function ( scene, camera, sortObjects, sortElements ) { + function LineBasicMaterial(parameters) { + Material.call(this); + this.type = 'LineBasicMaterial'; + this.color = new Color(0xffffff); + this.linewidth = 1; + this.linecap = 'round'; + this.linejoin = 'round'; + this.morphTargets = false; + this.setValues(parameters); + } + + LineBasicMaterial.prototype = Object.create(Material.prototype); + LineBasicMaterial.prototype.constructor = LineBasicMaterial; + LineBasicMaterial.prototype.isLineBasicMaterial = true; + + LineBasicMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.color.copy(source.color); + this.linewidth = source.linewidth; + this.linecap = source.linecap; + this.linejoin = source.linejoin; + this.morphTargets = source.morphTargets; + return this; + }; - var object, geometry, vertices, faces, face, faceVertexNormals, faceVertexUvs, - isFaceMaterial, objectMaterials; + var _start = new Vector3(); - _faceCount = 0; - _lineCount = 0; - _spriteCount = 0; + var _end = new Vector3(); - _renderData.elements.length = 0; + var _inverseMatrix$1 = new Matrix4(); - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - if ( camera.parent === undefined ) camera.updateMatrixWorld(); + var _ray$1 = new Ray(); - _viewMatrix.copy( camera.matrixWorldInverse.getInverse( camera.matrixWorld ) ); - _viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix ); + var _sphere$2 = new Sphere(); - _frustum.setFromMatrix( _viewProjectionMatrix ); + function Line(geometry, material, mode) { + if (mode === 1) { + console.error('THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead.'); + } - projectGraph( scene, sortObjects ); + Object3D.call(this); + this.type = 'Line'; + this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); + this.material = material !== undefined ? material : new LineBasicMaterial(); + this.updateMorphTargets(); + } - for ( var o = 0, ol = _renderData.objects.length; o < ol; o ++ ) { + Line.prototype = Object.assign(Object.create(Object3D.prototype), { + constructor: Line, + isLine: true, + copy: function copy(source) { + Object3D.prototype.copy.call(this, source); + this.material = source.material; + this.geometry = source.geometry; + return this; + }, + computeLineDistances: function computeLineDistances() { + var geometry = this.geometry; - object = _renderData.objects[ o ].object; - geometry = object.geometry; + if (geometry.isBufferGeometry) { + // we assume non-indexed geometry + if (geometry.index === null) { + var positionAttribute = geometry.attributes.position; + var lineDistances = [0]; - renderList.setObject( object ); + for (var i = 1, l = positionAttribute.count; i < l; i++) { + _start.fromBufferAttribute(positionAttribute, i - 1); - _modelMatrix = object.matrixWorld; + _end.fromBufferAttribute(positionAttribute, i); - _vertexCount = 0; + lineDistances[i] = lineDistances[i - 1]; + lineDistances[i] += _start.distanceTo(_end); + } - if ( object instanceof THREE.Mesh ) { + geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1)); + } else { + console.warn('THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.'); + } + } else if (geometry.isGeometry) { + var vertices = geometry.vertices; + var _lineDistances = geometry.lineDistances; + _lineDistances[0] = 0; - if ( geometry instanceof THREE.BufferGeometry ) { + for (var _i = 1, _l = vertices.length; _i < _l; _i++) { + _lineDistances[_i] = _lineDistances[_i - 1]; + _lineDistances[_i] += vertices[_i - 1].distanceTo(vertices[_i]); + } + } - var attributes = geometry.attributes; - var offsets = geometry.offsets; + return this; + }, + raycast: function raycast(raycaster, intersects) { + var geometry = this.geometry; + var matrixWorld = this.matrixWorld; + var threshold = raycaster.params.Line.threshold; // Checking boundingSphere distance to ray - if ( attributes.position === undefined ) continue; + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); - var positions = attributes.position.array; + _sphere$2.copy(geometry.boundingSphere); - for ( var i = 0, l = positions.length; i < l; i += 3 ) { + _sphere$2.applyMatrix4(matrixWorld); - renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ); + _sphere$2.radius += threshold; + if (raycaster.ray.intersectsSphere(_sphere$2) === false) return; // - } + _inverseMatrix$1.getInverse(matrixWorld); - if ( attributes.normal !== undefined ) { + _ray$1.copy(raycaster.ray).applyMatrix4(_inverseMatrix$1); - var normals = attributes.normal.array; + var localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); + var localThresholdSq = localThreshold * localThreshold; + var vStart = new Vector3(); + var vEnd = new Vector3(); + var interSegment = new Vector3(); + var interRay = new Vector3(); + var step = this.isLineSegments ? 2 : 1; - for ( var i = 0, l = normals.length; i < l; i += 3 ) { + if (geometry.isBufferGeometry) { + var index = geometry.index; + var attributes = geometry.attributes; + var positionAttribute = attributes.position; - renderList.pushNormal( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ); + if (index !== null) { + var indices = index.array; - } + for (var i = 0, l = indices.length - 1; i < l; i += step) { + var a = indices[i]; + var b = indices[i + 1]; + vStart.fromBufferAttribute(positionAttribute, a); + vEnd.fromBufferAttribute(positionAttribute, b); - } + var distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment); - if ( attributes.uv !== undefined ) { + if (distSq > localThresholdSq) continue; + interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation - var uvs = attributes.uv.array; + var distance = raycaster.ray.origin.distanceTo(interRay); + if (distance < raycaster.near || distance > raycaster.far) continue; + intersects.push({ + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4(this.matrixWorld), + index: i, + face: null, + faceIndex: null, + object: this + }); + } + } else { + for (var _i2 = 0, _l2 = positionAttribute.count - 1; _i2 < _l2; _i2 += step) { + vStart.fromBufferAttribute(positionAttribute, _i2); + vEnd.fromBufferAttribute(positionAttribute, _i2 + 1); - for ( var i = 0, l = uvs.length; i < l; i += 2 ) { + var _distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment); - renderList.pushUv( uvs[ i ], uvs[ i + 1 ] ); + if (_distSq > localThresholdSq) continue; + interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation - } + var _distance = raycaster.ray.origin.distanceTo(interRay); + if (_distance < raycaster.near || _distance > raycaster.far) continue; + intersects.push({ + distance: _distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4(this.matrixWorld), + index: _i2, + face: null, + faceIndex: null, + object: this + }); } + } + } else if (geometry.isGeometry) { + var vertices = geometry.vertices; + var nbVertices = vertices.length; - if ( attributes.index !== undefined ) { + for (var _i3 = 0; _i3 < nbVertices - 1; _i3 += step) { + var _distSq2 = _ray$1.distanceSqToSegment(vertices[_i3], vertices[_i3 + 1], interRay, interSegment); - var indices = attributes.index.array; + if (_distSq2 > localThresholdSq) continue; + interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation - if ( offsets.length > 0 ) { + var _distance2 = raycaster.ray.origin.distanceTo(interRay); - for ( var o = 0; o < offsets.length; o ++ ) { + if (_distance2 < raycaster.near || _distance2 > raycaster.far) continue; + intersects.push({ + distance: _distance2, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4(this.matrixWorld), + index: _i3, + face: null, + faceIndex: null, + object: this + }); + } + } + }, + updateMorphTargets: function updateMorphTargets() { + var geometry = this.geometry; - var offset = offsets[ o ]; - var index = offset.index; + if (geometry.isBufferGeometry) { + var morphAttributes = geometry.morphAttributes; + var keys = Object.keys(morphAttributes); - for ( var i = offset.start, l = offset.start + offset.count; i < l; i += 3 ) { + if (keys.length > 0) { + var morphAttribute = morphAttributes[keys[0]]; - renderList.pushTriangle( indices[ i ] + index, indices[ i + 1 ] + index, indices[ i + 2 ] + index ); + if (morphAttribute !== undefined) { + this.morphTargetInfluences = []; + this.morphTargetDictionary = {}; - } - - } - - } else { + for (var m = 0, ml = morphAttribute.length; m < ml; m++) { + var name = morphAttribute[m].name || String(m); + this.morphTargetInfluences.push(0); + this.morphTargetDictionary[name] = m; + } + } + } + } else { + var morphTargets = geometry.morphTargets; - for ( var i = 0, l = indices.length; i < l; i += 3 ) { + if (morphTargets !== undefined && morphTargets.length > 0) { + console.error('THREE.Line.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.'); + } + } + } + }); - renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); + var _start$1 = new Vector3(); - } + var _end$1 = new Vector3(); - } + function LineSegments(geometry, material) { + Line.call(this, geometry, material); + this.type = 'LineSegments'; + } - } else { + LineSegments.prototype = Object.assign(Object.create(Line.prototype), { + constructor: LineSegments, + isLineSegments: true, + computeLineDistances: function computeLineDistances() { + var geometry = this.geometry; - for ( var i = 0, l = positions.length / 3; i < l; i += 3 ) { + if (geometry.isBufferGeometry) { + // we assume non-indexed geometry + if (geometry.index === null) { + var positionAttribute = geometry.attributes.position; + var lineDistances = []; - renderList.pushTriangle( i, i + 1, i + 2 ); + for (var i = 0, l = positionAttribute.count; i < l; i += 2) { + _start$1.fromBufferAttribute(positionAttribute, i); - } + _end$1.fromBufferAttribute(positionAttribute, i + 1); + lineDistances[i] = i === 0 ? 0 : lineDistances[i - 1]; + lineDistances[i + 1] = lineDistances[i] + _start$1.distanceTo(_end$1); } - } else if ( geometry instanceof THREE.Geometry ) { + geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1)); + } else { + console.warn('THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.'); + } + } else if (geometry.isGeometry) { + var vertices = geometry.vertices; + var _lineDistances = geometry.lineDistances; - vertices = geometry.vertices; - faces = geometry.faces; - faceVertexUvs = geometry.faceVertexUvs[ 0 ]; + for (var _i = 0, _l = vertices.length; _i < _l; _i += 2) { + _start$1.copy(vertices[_i]); - _normalMatrix.getNormalMatrix( _modelMatrix ); + _end$1.copy(vertices[_i + 1]); - isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial; - objectMaterials = isFaceMaterial === true ? object.material : null; + _lineDistances[_i] = _i === 0 ? 0 : _lineDistances[_i - 1]; + _lineDistances[_i + 1] = _lineDistances[_i] + _start$1.distanceTo(_end$1); + } + } - for ( var v = 0, vl = vertices.length; v < vl; v ++ ) { + return this; + } + }); - var vertex = vertices[ v ]; - renderList.pushVertex( vertex.x, vertex.y, vertex.z ); + function LineLoop(geometry, material) { + Line.call(this, geometry, material); + this.type = 'LineLoop'; + } - } + LineLoop.prototype = Object.assign(Object.create(Line.prototype), { + constructor: LineLoop, + isLineLoop: true + }); - for ( var f = 0, fl = faces.length; f < fl; f ++ ) { + /** + * parameters = { + * color: , + * opacity: , + * map: new THREE.Texture( ), + * alphaMap: new THREE.Texture( ), + * + * size: , + * sizeAttenuation: + * + * morphTargets: + * } + */ - face = faces[ f ]; + function PointsMaterial(parameters) { + Material.call(this); + this.type = 'PointsMaterial'; + this.color = new Color(0xffffff); + this.map = null; + this.alphaMap = null; + this.size = 1; + this.sizeAttenuation = true; + this.morphTargets = false; + this.setValues(parameters); + } + + PointsMaterial.prototype = Object.create(Material.prototype); + PointsMaterial.prototype.constructor = PointsMaterial; + PointsMaterial.prototype.isPointsMaterial = true; + + PointsMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.color.copy(source.color); + this.map = source.map; + this.alphaMap = source.alphaMap; + this.size = source.size; + this.sizeAttenuation = source.sizeAttenuation; + this.morphTargets = source.morphTargets; + return this; + }; - var material = isFaceMaterial === true - ? objectMaterials.materials[ face.materialIndex ] - : object.material; + var _inverseMatrix$2 = new Matrix4(); - if ( material === undefined ) continue; + var _ray$2 = new Ray(); - var side = material.side; + var _sphere$3 = new Sphere(); - var v1 = _vertexPool[ face.a ]; - var v2 = _vertexPool[ face.b ]; - var v3 = _vertexPool[ face.c ]; + var _position$1 = new Vector3(); - if ( material.morphTargets === true ) { + function Points(geometry, material) { + Object3D.call(this); + this.type = 'Points'; + this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); + this.material = material !== undefined ? material : new PointsMaterial(); + this.updateMorphTargets(); + } - var morphTargets = geometry.morphTargets; - var morphInfluences = object.morphTargetInfluences; + Points.prototype = Object.assign(Object.create(Object3D.prototype), { + constructor: Points, + isPoints: true, + copy: function copy(source) { + Object3D.prototype.copy.call(this, source); + this.material = source.material; + this.geometry = source.geometry; + return this; + }, + raycast: function raycast(raycaster, intersects) { + var geometry = this.geometry; + var matrixWorld = this.matrixWorld; + var threshold = raycaster.params.Points.threshold; // Checking boundingSphere distance to ray - var v1p = v1.position; - var v2p = v2.position; - var v3p = v3.position; + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); - _vA.set( 0, 0, 0 ); - _vB.set( 0, 0, 0 ); - _vC.set( 0, 0, 0 ); + _sphere$3.copy(geometry.boundingSphere); - for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) { + _sphere$3.applyMatrix4(matrixWorld); - var influence = morphInfluences[ t ]; + _sphere$3.radius += threshold; + if (raycaster.ray.intersectsSphere(_sphere$3) === false) return; // - if ( influence === 0 ) continue; + _inverseMatrix$2.getInverse(matrixWorld); - var targets = morphTargets[ t ].vertices; + _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); - _vA.x += ( targets[ face.a ].x - v1p.x ) * influence; - _vA.y += ( targets[ face.a ].y - v1p.y ) * influence; - _vA.z += ( targets[ face.a ].z - v1p.z ) * influence; + var localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); + var localThresholdSq = localThreshold * localThreshold; - _vB.x += ( targets[ face.b ].x - v2p.x ) * influence; - _vB.y += ( targets[ face.b ].y - v2p.y ) * influence; - _vB.z += ( targets[ face.b ].z - v2p.z ) * influence; + if (geometry.isBufferGeometry) { + var index = geometry.index; + var attributes = geometry.attributes; + var positionAttribute = attributes.position; - _vC.x += ( targets[ face.c ].x - v3p.x ) * influence; - _vC.y += ( targets[ face.c ].y - v3p.y ) * influence; - _vC.z += ( targets[ face.c ].z - v3p.z ) * influence; + if (index !== null) { + var indices = index.array; - } + for (var i = 0, il = indices.length; i < il; i++) { + var a = indices[i]; - v1.position.add( _vA ); - v2.position.add( _vB ); - v3.position.add( _vC ); + _position$1.fromBufferAttribute(positionAttribute, a); - renderList.projectVertex( v1 ); - renderList.projectVertex( v2 ); - renderList.projectVertex( v3 ); + testPoint(_position$1, a, localThresholdSq, matrixWorld, raycaster, intersects, this); + } + } else { + for (var _i = 0, l = positionAttribute.count; _i < l; _i++) { + _position$1.fromBufferAttribute(positionAttribute, _i); - } + testPoint(_position$1, _i, localThresholdSq, matrixWorld, raycaster, intersects, this); + } + } + } else { + var vertices = geometry.vertices; - if ( renderList.checkTriangleVisibility( v1, v2, v3 ) === false ) continue; + for (var _i2 = 0, _l = vertices.length; _i2 < _l; _i2++) { + testPoint(vertices[_i2], _i2, localThresholdSq, matrixWorld, raycaster, intersects, this); + } + } + }, + updateMorphTargets: function updateMorphTargets() { + var geometry = this.geometry; - var visible = renderList.checkBackfaceCulling( v1, v2, v3 ); + if (geometry.isBufferGeometry) { + var morphAttributes = geometry.morphAttributes; + var keys = Object.keys(morphAttributes); - if ( side !== THREE.DoubleSide ) { - if ( side === THREE.FrontSide && visible === false ) continue; - if ( side === THREE.BackSide && visible === true ) continue; - } + if (keys.length > 0) { + var morphAttribute = morphAttributes[keys[0]]; - _face = getNextFaceInPool(); + if (morphAttribute !== undefined) { + this.morphTargetInfluences = []; + this.morphTargetDictionary = {}; - _face.id = object.id; - _face.v1.copy( v1 ); - _face.v2.copy( v2 ); - _face.v3.copy( v3 ); + for (var m = 0, ml = morphAttribute.length; m < ml; m++) { + var name = morphAttribute[m].name || String(m); + this.morphTargetInfluences.push(0); + this.morphTargetDictionary[name] = m; + } + } + } + } else { + var morphTargets = geometry.morphTargets; - _face.normalModel.copy( face.normal ); + if (morphTargets !== undefined && morphTargets.length > 0) { + console.error('THREE.Points.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.'); + } + } + } + }); - if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) { + function testPoint(point, index, localThresholdSq, matrixWorld, raycaster, intersects, object) { + var rayPointDistanceSq = _ray$2.distanceSqToPoint(point); - _face.normalModel.negate(); + if (rayPointDistanceSq < localThresholdSq) { + var intersectPoint = new Vector3(); - } + _ray$2.closestPointToPoint(point, intersectPoint); - _face.normalModel.applyMatrix3( _normalMatrix ).normalize(); + intersectPoint.applyMatrix4(matrixWorld); + var distance = raycaster.ray.origin.distanceTo(intersectPoint); + if (distance < raycaster.near || distance > raycaster.far) return; + intersects.push({ + distance: distance, + distanceToRay: Math.sqrt(rayPointDistanceSq), + point: intersectPoint, + index: index, + face: null, + object: object + }); + } + } - faceVertexNormals = face.vertexNormals; + function VideoTexture(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) { + Texture.call(this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); + this.format = format !== undefined ? format : RGBFormat; + this.minFilter = minFilter !== undefined ? minFilter : LinearFilter; + this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; + this.generateMipmaps = false; + var scope = this; - for ( var n = 0, nl = Math.min( faceVertexNormals.length, 3 ); n < nl; n ++ ) { + function updateVideo() { + scope.needsUpdate = true; + video.requestVideoFrameCallback(updateVideo); + } - var normalModel = _face.vertexNormalsModel[ n ]; - normalModel.copy( faceVertexNormals[ n ] ); + if ('requestVideoFrameCallback' in video) { + video.requestVideoFrameCallback(updateVideo); + } + } - if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) { + VideoTexture.prototype = Object.assign(Object.create(Texture.prototype), { + constructor: VideoTexture, + clone: function clone() { + return new this.constructor(this.image).copy(this); + }, + isVideoTexture: true, + update: function update() { + var video = this.image; + var hasVideoFrameCallback = ('requestVideoFrameCallback' in video); - normalModel.negate(); + if (hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA) { + this.needsUpdate = true; + } + } + }); - } + function CompressedTexture(mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding) { + Texture.call(this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); + this.image = { + width: width, + height: height + }; + this.mipmaps = mipmaps; // no flipping for cube textures + // (also flipping doesn't work for compressed textures ) - normalModel.applyMatrix3( _normalMatrix ).normalize(); + this.flipY = false; // can't generate mipmaps for compressed textures + // mips must be embedded in DDS files - } + this.generateMipmaps = false; + } - _face.vertexNormalsLength = faceVertexNormals.length; + CompressedTexture.prototype = Object.create(Texture.prototype); + CompressedTexture.prototype.constructor = CompressedTexture; + CompressedTexture.prototype.isCompressedTexture = true; - var vertexUvs = faceVertexUvs[ f ]; + function CanvasTexture(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) { + Texture.call(this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); + this.needsUpdate = true; + } - if ( vertexUvs !== undefined ) { + CanvasTexture.prototype = Object.create(Texture.prototype); + CanvasTexture.prototype.constructor = CanvasTexture; + CanvasTexture.prototype.isCanvasTexture = true; - for ( var u = 0; u < 3; u ++ ) { + function DepthTexture(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format) { + format = format !== undefined ? format : DepthFormat; - _face.uvs[ u ].copy( vertexUvs[ u ] ); + if (format !== DepthFormat && format !== DepthStencilFormat) { + throw new Error('DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat'); + } - } + if (type === undefined && format === DepthFormat) type = UnsignedShortType; + if (type === undefined && format === DepthStencilFormat) type = UnsignedInt248Type; + Texture.call(this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); + this.image = { + width: width, + height: height + }; + this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; + this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; + this.flipY = false; + this.generateMipmaps = false; + } + + DepthTexture.prototype = Object.create(Texture.prototype); + DepthTexture.prototype.constructor = DepthTexture; + DepthTexture.prototype.isDepthTexture = true; + + var _geometryId = 0; // Geometry uses even numbers as Id + + var _m1$3 = new Matrix4(); + + var _obj$1 = new Object3D(); + + var _offset$1 = new Vector3(); + + function Geometry() { + Object.defineProperty(this, 'id', { + value: _geometryId += 2 + }); + this.uuid = MathUtils.generateUUID(); + this.name = ''; + this.type = 'Geometry'; + this.vertices = []; + this.colors = []; + this.faces = []; + this.faceVertexUvs = [[]]; + this.morphTargets = []; + this.morphNormals = []; + this.skinWeights = []; + this.skinIndices = []; + this.lineDistances = []; + this.boundingBox = null; + this.boundingSphere = null; // update flags + + this.elementsNeedUpdate = false; + this.verticesNeedUpdate = false; + this.uvsNeedUpdate = false; + this.normalsNeedUpdate = false; + this.colorsNeedUpdate = false; + this.lineDistancesNeedUpdate = false; + this.groupsNeedUpdate = false; + } + + Geometry.prototype = Object.assign(Object.create(EventDispatcher.prototype), { + constructor: Geometry, + isGeometry: true, + applyMatrix4: function applyMatrix4(matrix) { + var normalMatrix = new Matrix3().getNormalMatrix(matrix); + + for (var i = 0, il = this.vertices.length; i < il; i++) { + var vertex = this.vertices[i]; + vertex.applyMatrix4(matrix); + } + + for (var _i = 0, _il = this.faces.length; _i < _il; _i++) { + var face = this.faces[_i]; + face.normal.applyMatrix3(normalMatrix).normalize(); + + for (var j = 0, jl = face.vertexNormals.length; j < jl; j++) { + face.vertexNormals[j].applyMatrix3(normalMatrix).normalize(); + } + } - } + if (this.boundingBox !== null) { + this.computeBoundingBox(); + } - _face.color = face.color; - _face.material = material; + if (this.boundingSphere !== null) { + this.computeBoundingSphere(); + } - _face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3; + this.verticesNeedUpdate = true; + this.normalsNeedUpdate = true; + return this; + }, + rotateX: function rotateX(angle) { + // rotate geometry around world x-axis + _m1$3.makeRotationX(angle); - _renderData.elements.push( _face ); + this.applyMatrix4(_m1$3); + return this; + }, + rotateY: function rotateY(angle) { + // rotate geometry around world y-axis + _m1$3.makeRotationY(angle); - } + this.applyMatrix4(_m1$3); + return this; + }, + rotateZ: function rotateZ(angle) { + // rotate geometry around world z-axis + _m1$3.makeRotationZ(angle); - } + this.applyMatrix4(_m1$3); + return this; + }, + translate: function translate(x, y, z) { + // translate geometry + _m1$3.makeTranslation(x, y, z); - } else if ( object instanceof THREE.Line ) { + this.applyMatrix4(_m1$3); + return this; + }, + scale: function scale(x, y, z) { + // scale geometry + _m1$3.makeScale(x, y, z); - if ( geometry instanceof THREE.BufferGeometry ) { + this.applyMatrix4(_m1$3); + return this; + }, + lookAt: function lookAt(vector) { + _obj$1.lookAt(vector); - var attributes = geometry.attributes; + _obj$1.updateMatrix(); - if ( attributes.position !== undefined ) { + this.applyMatrix4(_obj$1.matrix); + return this; + }, + fromBufferGeometry: function fromBufferGeometry(geometry) { + var scope = this; + var index = geometry.index !== null ? geometry.index : undefined; + var attributes = geometry.attributes; - var positions = attributes.position.array; + if (attributes.position === undefined) { + console.error('THREE.Geometry.fromBufferGeometry(): Position attribute required for conversion.'); + return this; + } - for ( var i = 0, l = positions.length; i < l; i += 3 ) { + var position = attributes.position; + var normal = attributes.normal; + var color = attributes.color; + var uv = attributes.uv; + var uv2 = attributes.uv2; + if (uv2 !== undefined) this.faceVertexUvs[1] = []; - renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ); + for (var i = 0; i < position.count; i++) { + scope.vertices.push(new Vector3().fromBufferAttribute(position, i)); - } + if (color !== undefined) { + scope.colors.push(new Color().fromBufferAttribute(color, i)); + } + } - if ( attributes.index !== undefined ) { + function addFace(a, b, c, materialIndex) { + var vertexColors = color === undefined ? [] : [scope.colors[a].clone(), scope.colors[b].clone(), scope.colors[c].clone()]; + var vertexNormals = normal === undefined ? [] : [new Vector3().fromBufferAttribute(normal, a), new Vector3().fromBufferAttribute(normal, b), new Vector3().fromBufferAttribute(normal, c)]; + var face = new Face3(a, b, c, vertexNormals, vertexColors, materialIndex); + scope.faces.push(face); - var indices = attributes.index.array; + if (uv !== undefined) { + scope.faceVertexUvs[0].push([new Vector2().fromBufferAttribute(uv, a), new Vector2().fromBufferAttribute(uv, b), new Vector2().fromBufferAttribute(uv, c)]); + } - for ( var i = 0, l = indices.length; i < l; i += 2 ) { + if (uv2 !== undefined) { + scope.faceVertexUvs[1].push([new Vector2().fromBufferAttribute(uv2, a), new Vector2().fromBufferAttribute(uv2, b), new Vector2().fromBufferAttribute(uv2, c)]); + } + } - renderList.pushLine( indices[ i ], indices[ i + 1 ] ); + var groups = geometry.groups; - } + if (groups.length > 0) { + for (var _i2 = 0; _i2 < groups.length; _i2++) { + var group = groups[_i2]; + var start = group.start; + var count = group.count; + for (var j = start, jl = start + count; j < jl; j += 3) { + if (index !== undefined) { + addFace(index.getX(j), index.getX(j + 1), index.getX(j + 2), group.materialIndex); } else { + addFace(j, j + 1, j + 2, group.materialIndex); + } + } + } + } else { + if (index !== undefined) { + for (var _i3 = 0; _i3 < index.count; _i3 += 3) { + addFace(index.getX(_i3), index.getX(_i3 + 1), index.getX(_i3 + 2)); + } + } else { + for (var _i4 = 0; _i4 < position.count; _i4 += 3) { + addFace(_i4, _i4 + 1, _i4 + 2); + } + } + } - for ( var i = 0, l = ( positions.length / 3 ) - 1; i < l; i ++ ) { + this.computeFaceNormals(); - renderList.pushLine( i, i + 1 ); + if (geometry.boundingBox !== null) { + this.boundingBox = geometry.boundingBox.clone(); + } - } + if (geometry.boundingSphere !== null) { + this.boundingSphere = geometry.boundingSphere.clone(); + } - } + return this; + }, + center: function center() { + this.computeBoundingBox(); + this.boundingBox.getCenter(_offset$1).negate(); + this.translate(_offset$1.x, _offset$1.y, _offset$1.z); + return this; + }, + normalize: function normalize() { + this.computeBoundingSphere(); + var center = this.boundingSphere.center; + var radius = this.boundingSphere.radius; + var s = radius === 0 ? 1 : 1.0 / radius; + var matrix = new Matrix4(); + matrix.set(s, 0, 0, -s * center.x, 0, s, 0, -s * center.y, 0, 0, s, -s * center.z, 0, 0, 0, 1); + this.applyMatrix4(matrix); + return this; + }, + computeFaceNormals: function computeFaceNormals() { + var cb = new Vector3(), + ab = new Vector3(); + + for (var f = 0, fl = this.faces.length; f < fl; f++) { + var face = this.faces[f]; + var vA = this.vertices[face.a]; + var vB = this.vertices[face.b]; + var vC = this.vertices[face.c]; + cb.subVectors(vC, vB); + ab.subVectors(vA, vB); + cb.cross(ab); + cb.normalize(); + face.normal.copy(cb); + } + }, + computeVertexNormals: function computeVertexNormals(areaWeighted) { + if (areaWeighted === undefined) areaWeighted = true; + var vertices = new Array(this.vertices.length); + + for (var v = 0, vl = this.vertices.length; v < vl; v++) { + vertices[v] = new Vector3(); + } + + if (areaWeighted) { + // vertex normals weighted by triangle areas + // http://www.iquilezles.org/www/articles/normals/normals.htm + var cb = new Vector3(), + ab = new Vector3(); + + for (var f = 0, fl = this.faces.length; f < fl; f++) { + var face = this.faces[f]; + var vA = this.vertices[face.a]; + var vB = this.vertices[face.b]; + var vC = this.vertices[face.c]; + cb.subVectors(vC, vB); + ab.subVectors(vA, vB); + cb.cross(ab); + vertices[face.a].add(cb); + vertices[face.b].add(cb); + vertices[face.c].add(cb); + } + } else { + this.computeFaceNormals(); - } + for (var _f = 0, _fl = this.faces.length; _f < _fl; _f++) { + var _face = this.faces[_f]; - } else if ( geometry instanceof THREE.Geometry ) { + vertices[_face.a].add(_face.normal); - _modelViewProjectionMatrix.multiplyMatrices( _viewProjectionMatrix, _modelMatrix ); + vertices[_face.b].add(_face.normal); - vertices = object.geometry.vertices; + vertices[_face.c].add(_face.normal); + } + } - if ( vertices.length === 0 ) continue; + for (var _v = 0, _vl = this.vertices.length; _v < _vl; _v++) { + vertices[_v].normalize(); + } - v1 = getNextVertexInPool(); - v1.positionScreen.copy( vertices[ 0 ] ).applyMatrix4( _modelViewProjectionMatrix ); + for (var _f2 = 0, _fl2 = this.faces.length; _f2 < _fl2; _f2++) { + var _face2 = this.faces[_f2]; + var vertexNormals = _face2.vertexNormals; - // Handle LineStrip and LinePieces - var step = object.type === THREE.LinePieces ? 2 : 1; + if (vertexNormals.length === 3) { + vertexNormals[0].copy(vertices[_face2.a]); + vertexNormals[1].copy(vertices[_face2.b]); + vertexNormals[2].copy(vertices[_face2.c]); + } else { + vertexNormals[0] = vertices[_face2.a].clone(); + vertexNormals[1] = vertices[_face2.b].clone(); + vertexNormals[2] = vertices[_face2.c].clone(); + } + } - for ( var v = 1, vl = vertices.length; v < vl; v ++ ) { + if (this.faces.length > 0) { + this.normalsNeedUpdate = true; + } + }, + computeFlatVertexNormals: function computeFlatVertexNormals() { + this.computeFaceNormals(); - v1 = getNextVertexInPool(); - v1.positionScreen.copy( vertices[ v ] ).applyMatrix4( _modelViewProjectionMatrix ); + for (var f = 0, fl = this.faces.length; f < fl; f++) { + var face = this.faces[f]; + var vertexNormals = face.vertexNormals; - if ( ( v + 1 ) % step > 0 ) continue; + if (vertexNormals.length === 3) { + vertexNormals[0].copy(face.normal); + vertexNormals[1].copy(face.normal); + vertexNormals[2].copy(face.normal); + } else { + vertexNormals[0] = face.normal.clone(); + vertexNormals[1] = face.normal.clone(); + vertexNormals[2] = face.normal.clone(); + } + } - v2 = _vertexPool[ _vertexCount - 2 ]; + if (this.faces.length > 0) { + this.normalsNeedUpdate = true; + } + }, + computeMorphNormals: function computeMorphNormals() { + // save original normals + // - create temp variables on first access + // otherwise just copy (for faster repeated calls) + for (var f = 0, fl = this.faces.length; f < fl; f++) { + var face = this.faces[f]; + + if (!face.__originalFaceNormal) { + face.__originalFaceNormal = face.normal.clone(); + } else { + face.__originalFaceNormal.copy(face.normal); + } - _clippedVertex1PositionScreen.copy( v1.positionScreen ); - _clippedVertex2PositionScreen.copy( v2.positionScreen ); + if (!face.__originalVertexNormals) face.__originalVertexNormals = []; - if ( clipLine( _clippedVertex1PositionScreen, _clippedVertex2PositionScreen ) === true ) { + for (var i = 0, il = face.vertexNormals.length; i < il; i++) { + if (!face.__originalVertexNormals[i]) { + face.__originalVertexNormals[i] = face.vertexNormals[i].clone(); + } else { + face.__originalVertexNormals[i].copy(face.vertexNormals[i]); + } + } + } // use temp geometry to compute face and vertex normals for each morph + + + var tmpGeo = new Geometry(); + tmpGeo.faces = this.faces; + + for (var _i5 = 0, _il2 = this.morphTargets.length; _i5 < _il2; _i5++) { + // create on first access + if (!this.morphNormals[_i5]) { + this.morphNormals[_i5] = {}; + this.morphNormals[_i5].faceNormals = []; + this.morphNormals[_i5].vertexNormals = []; + var dstNormalsFace = this.morphNormals[_i5].faceNormals; + var dstNormalsVertex = this.morphNormals[_i5].vertexNormals; + + for (var _f3 = 0, _fl3 = this.faces.length; _f3 < _fl3; _f3++) { + var faceNormal = new Vector3(); + var vertexNormals = { + a: new Vector3(), + b: new Vector3(), + c: new Vector3() + }; + dstNormalsFace.push(faceNormal); + dstNormalsVertex.push(vertexNormals); + } + } - // Perform the perspective divide - _clippedVertex1PositionScreen.multiplyScalar( 1 / _clippedVertex1PositionScreen.w ); - _clippedVertex2PositionScreen.multiplyScalar( 1 / _clippedVertex2PositionScreen.w ); + var morphNormals = this.morphNormals[_i5]; // set vertices to morph target - _line = getNextLineInPool(); + tmpGeo.vertices = this.morphTargets[_i5].vertices; // compute morph normals - _line.id = object.id; - _line.v1.positionScreen.copy( _clippedVertex1PositionScreen ); - _line.v2.positionScreen.copy( _clippedVertex2PositionScreen ); + tmpGeo.computeFaceNormals(); + tmpGeo.computeVertexNormals(); // store morph normals - _line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z ); + for (var _f4 = 0, _fl4 = this.faces.length; _f4 < _fl4; _f4++) { + var _face3 = this.faces[_f4]; + var _faceNormal = morphNormals.faceNormals[_f4]; + var _vertexNormals = morphNormals.vertexNormals[_f4]; - _line.material = object.material; + _faceNormal.copy(_face3.normal); - if ( object.material.vertexColors === THREE.VertexColors ) { + _vertexNormals.a.copy(_face3.vertexNormals[0]); - _line.vertexColors[ 0 ].copy( object.geometry.colors[ v ] ); - _line.vertexColors[ 1 ].copy( object.geometry.colors[ v - 1 ] ); + _vertexNormals.b.copy(_face3.vertexNormals[1]); - } + _vertexNormals.c.copy(_face3.vertexNormals[2]); + } + } // restore original normals - _renderData.elements.push( _line ); - } + for (var _f5 = 0, _fl5 = this.faces.length; _f5 < _fl5; _f5++) { + var _face4 = this.faces[_f5]; + _face4.normal = _face4.__originalFaceNormal; + _face4.vertexNormals = _face4.__originalVertexNormals; + } + }, + computeBoundingBox: function computeBoundingBox() { + if (this.boundingBox === null) { + this.boundingBox = new Box3(); + } - } + this.boundingBox.setFromPoints(this.vertices); + }, + computeBoundingSphere: function computeBoundingSphere() { + if (this.boundingSphere === null) { + this.boundingSphere = new Sphere(); + } + this.boundingSphere.setFromPoints(this.vertices); + }, + merge: function merge(geometry, matrix, materialIndexOffset) { + if (!(geometry && geometry.isGeometry)) { + console.error('THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry); + return; + } + + var normalMatrix; + var vertexOffset = this.vertices.length, + vertices1 = this.vertices, + vertices2 = geometry.vertices, + faces1 = this.faces, + faces2 = geometry.faces, + colors1 = this.colors, + colors2 = geometry.colors; + if (materialIndexOffset === undefined) materialIndexOffset = 0; + + if (matrix !== undefined) { + normalMatrix = new Matrix3().getNormalMatrix(matrix); + } // vertices + + + for (var i = 0, il = vertices2.length; i < il; i++) { + var vertex = vertices2[i]; + var vertexCopy = vertex.clone(); + if (matrix !== undefined) vertexCopy.applyMatrix4(matrix); + vertices1.push(vertexCopy); + } // colors + + + for (var _i6 = 0, _il3 = colors2.length; _i6 < _il3; _i6++) { + colors1.push(colors2[_i6].clone()); + } // faces + + + for (var _i7 = 0, _il4 = faces2.length; _i7 < _il4; _i7++) { + var face = faces2[_i7]; + var normal = void 0, + color = void 0; + var faceVertexNormals = face.vertexNormals, + faceVertexColors = face.vertexColors; + var faceCopy = new Face3(face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset); + faceCopy.normal.copy(face.normal); + + if (normalMatrix !== undefined) { + faceCopy.normal.applyMatrix3(normalMatrix).normalize(); } - } else if ( object instanceof THREE.Sprite ) { + for (var j = 0, jl = faceVertexNormals.length; j < jl; j++) { + normal = faceVertexNormals[j].clone(); - _vector4.set( _modelMatrix.elements[12], _modelMatrix.elements[13], _modelMatrix.elements[14], 1 ); - _vector4.applyMatrix4( _viewProjectionMatrix ); + if (normalMatrix !== undefined) { + normal.applyMatrix3(normalMatrix).normalize(); + } - var invW = 1 / _vector4.w; + faceCopy.vertexNormals.push(normal); + } - _vector4.z *= invW; + faceCopy.color.copy(face.color); - if ( _vector4.z >= -1 && _vector4.z <= 1 ) { + for (var _j = 0, _jl = faceVertexColors.length; _j < _jl; _j++) { + color = faceVertexColors[_j]; + faceCopy.vertexColors.push(color.clone()); + } - _sprite = getNextSpriteInPool(); - _sprite.id = object.id; - _sprite.x = _vector4.x * invW; - _sprite.y = _vector4.y * invW; - _sprite.z = _vector4.z; - _sprite.object = object; + faceCopy.materialIndex = face.materialIndex + materialIndexOffset; + faces1.push(faceCopy); + } // uvs - _sprite.rotation = object.rotation; - _sprite.scale.x = object.scale.x * Math.abs( _sprite.x - ( _vector4.x + camera.projectionMatrix.elements[0] ) / ( _vector4.w + camera.projectionMatrix.elements[12] ) ); - _sprite.scale.y = object.scale.y * Math.abs( _sprite.y - ( _vector4.y + camera.projectionMatrix.elements[5] ) / ( _vector4.w + camera.projectionMatrix.elements[13] ) ); + for (var _i8 = 0, _il5 = geometry.faceVertexUvs.length; _i8 < _il5; _i8++) { + var faceVertexUvs2 = geometry.faceVertexUvs[_i8]; + if (this.faceVertexUvs[_i8] === undefined) this.faceVertexUvs[_i8] = []; - _sprite.material = object.material; + for (var _j2 = 0, _jl2 = faceVertexUvs2.length; _j2 < _jl2; _j2++) { + var uvs2 = faceVertexUvs2[_j2], + uvsCopy = []; - _renderData.elements.push( _sprite ); + for (var k = 0, kl = uvs2.length; k < kl; k++) { + uvsCopy.push(uvs2[k].clone()); + } + this.faceVertexUvs[_i8].push(uvsCopy); } - + } + }, + mergeMesh: function mergeMesh(mesh) { + if (!(mesh && mesh.isMesh)) { + console.error('THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh); + return; } - } + if (mesh.matrixAutoUpdate) mesh.updateMatrix(); + this.merge(mesh.geometry, mesh.matrix); + }, - if ( sortElements === true ) _renderData.elements.sort( painterSort ); + /* + * Checks for duplicate vertices with hashmap. + * Duplicated vertices are removed + * and faces' vertices are updated. + */ + mergeVertices: function mergeVertices() { + var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique) + + var unique = [], + changes = []; + var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001 + + var precision = Math.pow(10, precisionPoints); + + for (var i = 0, il = this.vertices.length; i < il; i++) { + var v = this.vertices[i]; + var key = Math.round(v.x * precision) + '_' + Math.round(v.y * precision) + '_' + Math.round(v.z * precision); + + if (verticesMap[key] === undefined) { + verticesMap[key] = i; + unique.push(this.vertices[i]); + changes[i] = unique.length - 1; + } else { + //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]); + changes[i] = changes[verticesMap[key]]; + } + } // if faces are completely degenerate after merging vertices, we + // have to remove them from the geometry. - return _renderData; - }; + var faceIndicesToRemove = []; - // Pools + for (var _i9 = 0, _il6 = this.faces.length; _i9 < _il6; _i9++) { + var face = this.faces[_i9]; + face.a = changes[face.a]; + face.b = changes[face.b]; + face.c = changes[face.c]; + var indices = [face.a, face.b, face.c]; // if any duplicate vertices are found in a Face3 + // we have to remove the face as nothing can be saved - function getNextObjectInPool() { + for (var n = 0; n < 3; n++) { + if (indices[n] === indices[(n + 1) % 3]) { + faceIndicesToRemove.push(_i9); + break; + } + } + } - if ( _objectCount === _objectPoolLength ) { + for (var _i10 = faceIndicesToRemove.length - 1; _i10 >= 0; _i10--) { + var idx = faceIndicesToRemove[_i10]; + this.faces.splice(idx, 1); - var object = new THREE.RenderableObject(); - _objectPool.push( object ); - _objectPoolLength ++; - _objectCount ++; - return object; + for (var j = 0, jl = this.faceVertexUvs.length; j < jl; j++) { + this.faceVertexUvs[j].splice(idx, 1); + } + } // Use unique set of vertices - } - return _objectPool[ _objectCount ++ ]; + var diff = this.vertices.length - unique.length; + this.vertices = unique; + return diff; + }, + setFromPoints: function setFromPoints(points) { + this.vertices = []; - } + for (var i = 0, l = points.length; i < l; i++) { + var point = points[i]; + this.vertices.push(new Vector3(point.x, point.y, point.z || 0)); + } - function getNextVertexInPool() { + return this; + }, + sortFacesByMaterialIndex: function sortFacesByMaterialIndex() { + var faces = this.faces; + var length = faces.length; // tag faces - if ( _vertexCount === _vertexPoolLength ) { + for (var i = 0; i < length; i++) { + faces[i]._id = i; + } // sort faces - var vertex = new THREE.RenderableVertex(); - _vertexPool.push( vertex ); - _vertexPoolLength ++; - _vertexCount ++; - return vertex; - } + function materialIndexSort(a, b) { + return a.materialIndex - b.materialIndex; + } - return _vertexPool[ _vertexCount ++ ]; + faces.sort(materialIndexSort); // sort uvs - } + var uvs1 = this.faceVertexUvs[0]; + var uvs2 = this.faceVertexUvs[1]; + var newUvs1, newUvs2; + if (uvs1 && uvs1.length === length) newUvs1 = []; + if (uvs2 && uvs2.length === length) newUvs2 = []; - function getNextFaceInPool() { + for (var _i11 = 0; _i11 < length; _i11++) { + var id = faces[_i11]._id; + if (newUvs1) newUvs1.push(uvs1[id]); + if (newUvs2) newUvs2.push(uvs2[id]); + } - if ( _faceCount === _facePoolLength ) { + if (newUvs1) this.faceVertexUvs[0] = newUvs1; + if (newUvs2) this.faceVertexUvs[1] = newUvs2; + }, + toJSON: function toJSON() { + var data = { + metadata: { + version: 4.5, + type: 'Geometry', + generator: 'Geometry.toJSON' + } + }; // standard Geometry serialization - var face = new THREE.RenderableFace(); - _facePool.push( face ); - _facePoolLength ++; - _faceCount ++; - return face; + data.uuid = this.uuid; + data.type = this.type; + if (this.name !== '') data.name = this.name; - } + if (this.parameters !== undefined) { + var parameters = this.parameters; - return _facePool[ _faceCount ++ ]; + for (var key in parameters) { + if (parameters[key] !== undefined) data[key] = parameters[key]; + } + return data; + } + + var vertices = []; + + for (var i = 0; i < this.vertices.length; i++) { + var vertex = this.vertices[i]; + vertices.push(vertex.x, vertex.y, vertex.z); + } + + var faces = []; + var normals = []; + var normalsHash = {}; + var colors = []; + var colorsHash = {}; + var uvs = []; + var uvsHash = {}; + + for (var _i12 = 0; _i12 < this.faces.length; _i12++) { + var face = this.faces[_i12]; + var hasMaterial = true; + var hasFaceUv = false; // deprecated + + var hasFaceVertexUv = this.faceVertexUvs[0][_i12] !== undefined; + var hasFaceNormal = face.normal.length() > 0; + var hasFaceVertexNormal = face.vertexNormals.length > 0; + var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1; + var hasFaceVertexColor = face.vertexColors.length > 0; + var faceType = 0; + faceType = setBit(faceType, 0, 0); // isQuad + + faceType = setBit(faceType, 1, hasMaterial); + faceType = setBit(faceType, 2, hasFaceUv); + faceType = setBit(faceType, 3, hasFaceVertexUv); + faceType = setBit(faceType, 4, hasFaceNormal); + faceType = setBit(faceType, 5, hasFaceVertexNormal); + faceType = setBit(faceType, 6, hasFaceColor); + faceType = setBit(faceType, 7, hasFaceVertexColor); + faces.push(faceType); + faces.push(face.a, face.b, face.c); + faces.push(face.materialIndex); + + if (hasFaceVertexUv) { + var faceVertexUvs = this.faceVertexUvs[0][_i12]; + faces.push(getUvIndex(faceVertexUvs[0]), getUvIndex(faceVertexUvs[1]), getUvIndex(faceVertexUvs[2])); + } - } + if (hasFaceNormal) { + faces.push(getNormalIndex(face.normal)); + } - function getNextLineInPool() { + if (hasFaceVertexNormal) { + var vertexNormals = face.vertexNormals; + faces.push(getNormalIndex(vertexNormals[0]), getNormalIndex(vertexNormals[1]), getNormalIndex(vertexNormals[2])); + } - if ( _lineCount === _linePoolLength ) { + if (hasFaceColor) { + faces.push(getColorIndex(face.color)); + } - var line = new THREE.RenderableLine(); - _linePool.push( line ); - _linePoolLength ++; - _lineCount ++ - return line; + if (hasFaceVertexColor) { + var vertexColors = face.vertexColors; + faces.push(getColorIndex(vertexColors[0]), getColorIndex(vertexColors[1]), getColorIndex(vertexColors[2])); + } + } - } + function setBit(value, position, enabled) { + return enabled ? value | 1 << position : value & ~(1 << position); + } - return _linePool[ _lineCount ++ ]; + function getNormalIndex(normal) { + var hash = normal.x.toString() + normal.y.toString() + normal.z.toString(); - } + if (normalsHash[hash] !== undefined) { + return normalsHash[hash]; + } - function getNextSpriteInPool() { + normalsHash[hash] = normals.length / 3; + normals.push(normal.x, normal.y, normal.z); + return normalsHash[hash]; + } - if ( _spriteCount === _spritePoolLength ) { + function getColorIndex(color) { + var hash = color.r.toString() + color.g.toString() + color.b.toString(); - var sprite = new THREE.RenderableSprite(); - _spritePool.push( sprite ); - _spritePoolLength ++; - _spriteCount ++ - return sprite; + if (colorsHash[hash] !== undefined) { + return colorsHash[hash]; + } - } + colorsHash[hash] = colors.length; + colors.push(color.getHex()); + return colorsHash[hash]; + } - return _spritePool[ _spriteCount ++ ]; + function getUvIndex(uv) { + var hash = uv.x.toString() + uv.y.toString(); - } + if (uvsHash[hash] !== undefined) { + return uvsHash[hash]; + } - // + uvsHash[hash] = uvs.length / 2; + uvs.push(uv.x, uv.y); + return uvsHash[hash]; + } - function painterSort( a, b ) { + data.data = {}; + data.data.vertices = vertices; + data.data.normals = normals; + if (colors.length > 0) data.data.colors = colors; + if (uvs.length > 0) data.data.uvs = [uvs]; // temporal backward compatibility - if ( a.z !== b.z ) { + data.data.faces = faces; + return data; + }, + clone: function clone() { + /* + // Handle primitives + const parameters = this.parameters; + if ( parameters !== undefined ) { + const values = []; + for ( const key in parameters ) { + values.push( parameters[ key ] ); + } + const geometry = Object.create( this.constructor.prototype ); + this.constructor.apply( geometry, values ); + return geometry; + } + return new this.constructor().copy( this ); + */ + return new Geometry().copy(this); + }, + copy: function copy(source) { + // reset + this.vertices = []; + this.colors = []; + this.faces = []; + this.faceVertexUvs = [[]]; + this.morphTargets = []; + this.morphNormals = []; + this.skinWeights = []; + this.skinIndices = []; + this.lineDistances = []; + this.boundingBox = null; + this.boundingSphere = null; // name - return b.z - a.z; + this.name = source.name; // vertices - } else if ( a.id !== b.id ) { + var vertices = source.vertices; - return a.id - b.id; + for (var i = 0, il = vertices.length; i < il; i++) { + this.vertices.push(vertices[i].clone()); + } // colors - } else { - return 0; + var colors = source.colors; - } + for (var _i13 = 0, _il7 = colors.length; _i13 < _il7; _i13++) { + this.colors.push(colors[_i13].clone()); + } // faces - } - function clipLine( s1, s2 ) { + var faces = source.faces; - var alpha1 = 0, alpha2 = 1, + for (var _i14 = 0, _il8 = faces.length; _i14 < _il8; _i14++) { + this.faces.push(faces[_i14].clone()); + } // face vertex uvs - // Calculate the boundary coordinate of each vertex for the near and far clip planes, - // Z = -1 and Z = +1, respectively. - bc1near = s1.z + s1.w, - bc2near = s2.z + s2.w, - bc1far = - s1.z + s1.w, - bc2far = - s2.z + s2.w; - if ( bc1near >= 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0 ) { + for (var _i15 = 0, _il9 = source.faceVertexUvs.length; _i15 < _il9; _i15++) { + var faceVertexUvs = source.faceVertexUvs[_i15]; - // Both vertices lie entirely within all clip planes. - return true; + if (this.faceVertexUvs[_i15] === undefined) { + this.faceVertexUvs[_i15] = []; + } - } else if ( ( bc1near < 0 && bc2near < 0) || (bc1far < 0 && bc2far < 0 ) ) { + for (var j = 0, jl = faceVertexUvs.length; j < jl; j++) { + var uvs = faceVertexUvs[j], + uvsCopy = []; - // Both vertices lie entirely outside one of the clip planes. - return false; + for (var k = 0, kl = uvs.length; k < kl; k++) { + var uv = uvs[k]; + uvsCopy.push(uv.clone()); + } - } else { + this.faceVertexUvs[_i15].push(uvsCopy); + } + } // morph targets - // The line segment spans at least one clip plane. - if ( bc1near < 0 ) { + var morphTargets = source.morphTargets; - // v1 lies outside the near plane, v2 inside - alpha1 = Math.max( alpha1, bc1near / ( bc1near - bc2near ) ); + for (var _i16 = 0, _il10 = morphTargets.length; _i16 < _il10; _i16++) { + var morphTarget = {}; + morphTarget.name = morphTargets[_i16].name; // vertices - } else if ( bc2near < 0 ) { + if (morphTargets[_i16].vertices !== undefined) { + morphTarget.vertices = []; - // v2 lies outside the near plane, v1 inside - alpha2 = Math.min( alpha2, bc1near / ( bc1near - bc2near ) ); + for (var _j3 = 0, _jl3 = morphTargets[_i16].vertices.length; _j3 < _jl3; _j3++) { + morphTarget.vertices.push(morphTargets[_i16].vertices[_j3].clone()); + } + } // normals - } - if ( bc1far < 0 ) { + if (morphTargets[_i16].normals !== undefined) { + morphTarget.normals = []; - // v1 lies outside the far plane, v2 inside - alpha1 = Math.max( alpha1, bc1far / ( bc1far - bc2far ) ); + for (var _j4 = 0, _jl4 = morphTargets[_i16].normals.length; _j4 < _jl4; _j4++) { + morphTarget.normals.push(morphTargets[_i16].normals[_j4].clone()); + } + } - } else if ( bc2far < 0 ) { + this.morphTargets.push(morphTarget); + } // morph normals - // v2 lies outside the far plane, v2 inside - alpha2 = Math.min( alpha2, bc1far / ( bc1far - bc2far ) ); - } + var morphNormals = source.morphNormals; - if ( alpha2 < alpha1 ) { + for (var _i17 = 0, _il11 = morphNormals.length; _i17 < _il11; _i17++) { + var morphNormal = {}; // vertex normals - // The line segment spans two boundaries, but is outside both of them. - // (This can't happen when we're only clipping against just near/far but good - // to leave the check here for future usage if other clip planes are added.) - return false; + if (morphNormals[_i17].vertexNormals !== undefined) { + morphNormal.vertexNormals = []; - } else { + for (var _j5 = 0, _jl5 = morphNormals[_i17].vertexNormals.length; _j5 < _jl5; _j5++) { + var srcVertexNormal = morphNormals[_i17].vertexNormals[_j5]; + var destVertexNormal = {}; + destVertexNormal.a = srcVertexNormal.a.clone(); + destVertexNormal.b = srcVertexNormal.b.clone(); + destVertexNormal.c = srcVertexNormal.c.clone(); + morphNormal.vertexNormals.push(destVertexNormal); + } + } // face normals - // Update the s1 and s2 vertices to match the clipped line segment. - s1.lerp( s2, alpha1 ); - s2.lerp( s1, 1 - alpha2 ); - return true; + if (morphNormals[_i17].faceNormals !== undefined) { + morphNormal.faceNormals = []; - } + for (var _j6 = 0, _jl6 = morphNormals[_i17].faceNormals.length; _j6 < _jl6; _j6++) { + morphNormal.faceNormals.push(morphNormals[_i17].faceNormals[_j6].clone()); + } + } - } + this.morphNormals.push(morphNormal); + } // skin weights - } -}; + var skinWeights = source.skinWeights; -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + for (var _i18 = 0, _il12 = skinWeights.length; _i18 < _il12; _i18++) { + this.skinWeights.push(skinWeights[_i18].clone()); + } // skin indices -THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) { - this.a = a; - this.b = b; - this.c = c; + var skinIndices = source.skinIndices; - this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3(); - this.vertexNormals = normal instanceof Array ? normal : [ ]; + for (var _i19 = 0, _il13 = skinIndices.length; _i19 < _il13; _i19++) { + this.skinIndices.push(skinIndices[_i19].clone()); + } // line distances - this.color = color instanceof THREE.Color ? color : new THREE.Color(); - this.vertexColors = color instanceof Array ? color : []; - this.vertexTangents = []; + var lineDistances = source.lineDistances; - this.materialIndex = materialIndex !== undefined ? materialIndex : 0; + for (var _i20 = 0, _il14 = lineDistances.length; _i20 < _il14; _i20++) { + this.lineDistances.push(lineDistances[_i20]); + } // bounding box -}; -THREE.Face3.prototype = { + var boundingBox = source.boundingBox; - constructor: THREE.Face3, + if (boundingBox !== null) { + this.boundingBox = boundingBox.clone(); + } // bounding sphere - clone: function () { - var face = new THREE.Face3( this.a, this.b, this.c ); + var boundingSphere = source.boundingSphere; - face.normal.copy( this.normal ); - face.color.copy( this.color ); + if (boundingSphere !== null) { + this.boundingSphere = boundingSphere.clone(); + } // update flags - face.materialIndex = this.materialIndex; - var i, il; - for ( i = 0, il = this.vertexNormals.length; i < il; i ++ ) face.vertexNormals[ i ] = this.vertexNormals[ i ].clone(); - for ( i = 0, il = this.vertexColors.length; i < il; i ++ ) face.vertexColors[ i ] = this.vertexColors[ i ].clone(); - for ( i = 0, il = this.vertexTangents.length; i < il; i ++ ) face.vertexTangents[ i ] = this.vertexTangents[ i ].clone(); + this.elementsNeedUpdate = source.elementsNeedUpdate; + this.verticesNeedUpdate = source.verticesNeedUpdate; + this.uvsNeedUpdate = source.uvsNeedUpdate; + this.normalsNeedUpdate = source.normalsNeedUpdate; + this.colorsNeedUpdate = source.colorsNeedUpdate; + this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate; + this.groupsNeedUpdate = source.groupsNeedUpdate; + return this; + }, + dispose: function dispose() { + this.dispatchEvent({ + type: 'dispose' + }); + } + }); - return face; + var BoxGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(BoxGeometry, _Geometry); - } + function BoxGeometry(width, height, depth, widthSegments, heightSegments, depthSegments) { + var _this; -}; + _this = _Geometry.call(this) || this; + _this.type = 'BoxGeometry'; + _this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; -/** - * @author mrdoob / http://mrdoob.com/ - */ + _this.fromBufferGeometry(new BoxBufferGeometry(width, height, depth, widthSegments, heightSegments, depthSegments)); -THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) { + _this.mergeVertices(); - console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.') + return _this; + } - return new THREE.Face3( a, b, c, normal, color, materialIndex ); + return BoxGeometry; + }(Geometry); -}; + var CircleBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(CircleBufferGeometry, _BufferGeometry); -/** - * @author mrdoob / http://mrdoob.com/ - */ + function CircleBufferGeometry(radius, segments, thetaStart, thetaLength) { + var _this; -THREE.BufferAttribute = function () {}; + _this = _BufferGeometry.call(this) || this; + _this.type = 'CircleBufferGeometry'; + _this.parameters = { + radius: radius, + segments: segments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + radius = radius || 1; + segments = segments !== undefined ? Math.max(3, segments) : 8; + thetaStart = thetaStart !== undefined ? thetaStart : 0; + thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; // buffers -THREE.BufferAttribute.prototype = { + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; // helper variables - constructor: THREE.BufferAttribute, + var vertex = new Vector3(); + var uv = new Vector2(); // center point - get length () { + vertices.push(0, 0, 0); + normals.push(0, 0, 1); + uvs.push(0.5, 0.5); - return this.array.length; + for (var s = 0, i = 3; s <= segments; s++, i += 3) { + var segment = thetaStart + s / segments * thetaLength; // vertex - }, + vertex.x = radius * Math.cos(segment); + vertex.y = radius * Math.sin(segment); + vertices.push(vertex.x, vertex.y, vertex.z); // normal - set: function ( value ) { + normals.push(0, 0, 1); // uvs - this.array.set( value ); + uv.x = (vertices[i] / radius + 1) / 2; + uv.y = (vertices[i + 1] / radius + 1) / 2; + uvs.push(uv.x, uv.y); + } // indices - }, - setX: function ( index, x ) { + for (var _i = 1; _i <= segments; _i++) { + indices.push(_i, _i + 1, 0); + } // build geometry - this.array[ index * this.itemSize ] = x; - }, + _this.setIndex(indices); - setY: function ( index, y ) { + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - this.array[ index * this.itemSize + 1 ] = y; + _this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - }, + _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - setZ: function ( index, z ) { + return _this; + } - this.array[ index * this.itemSize + 2 ] = z; + return CircleBufferGeometry; + }(BufferGeometry); - }, + var CircleGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(CircleGeometry, _Geometry); - setXY: function ( index, x, y ) { + function CircleGeometry(radius, segments, thetaStart, thetaLength) { + var _this; - index *= this.itemSize; + _this = _Geometry.call(this) || this; + _this.type = 'CircleGeometry'; + _this.parameters = { + radius: radius, + segments: segments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - this.array[ index ] = x; - this.array[ index + 1 ] = y; + _this.fromBufferGeometry(new CircleBufferGeometry(radius, segments, thetaStart, thetaLength)); - }, + _this.mergeVertices(); - setXYZ: function ( index, x, y, z ) { + return _this; + } - index *= this.itemSize; + return CircleGeometry; + }(Geometry); - this.array[ index ] = x; - this.array[ index + 1 ] = y; - this.array[ index + 2 ] = z; + var CylinderBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(CylinderBufferGeometry, _BufferGeometry); - }, + function CylinderBufferGeometry(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) { + var _this; - setXYZW: function ( index, x, y, z, w ) { + _this = _BufferGeometry.call(this) || this; + _this.type = 'CylinderBufferGeometry'; + _this.parameters = { + radiusTop: radiusTop, + radiusBottom: radiusBottom, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - index *= this.itemSize; + var scope = _assertThisInitialized(_this); - this.array[ index ] = x; - this.array[ index + 1 ] = y; - this.array[ index + 2 ] = z; - this.array[ index + 3 ] = w; + radiusTop = radiusTop !== undefined ? radiusTop : 1; + radiusBottom = radiusBottom !== undefined ? radiusBottom : 1; + height = height || 1; + radialSegments = Math.floor(radialSegments) || 8; + heightSegments = Math.floor(heightSegments) || 1; + openEnded = openEnded !== undefined ? openEnded : false; + thetaStart = thetaStart !== undefined ? thetaStart : 0.0; + thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; // buffers - } + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; // helper variables + + var index = 0; + var indexArray = []; + var halfHeight = height / 2; + var groupStart = 0; // generate geometry -}; + generateTorso(); -// + if (openEnded === false) { + if (radiusTop > 0) generateCap(true); + if (radiusBottom > 0) generateCap(false); + } // build geometry -THREE.Int8Attribute = function ( size, itemSize ) { - this.array = new Int8Array( size * itemSize ); - this.itemSize = itemSize; + _this.setIndex(indices); -}; + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); -THREE.Int8Attribute.prototype = Object.create( THREE.BufferAttribute.prototype ); + _this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); -THREE.Uint8Attribute = function ( size, itemSize ) { + _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); - this.array = new Uint8Array( size * itemSize ); - this.itemSize = itemSize; + function generateTorso() { + var normal = new Vector3(); + var vertex = new Vector3(); + var groupCount = 0; // this will be used to calculate the normal -}; + var slope = (radiusBottom - radiusTop) / height; // generate vertices, normals and uvs -THREE.Uint8Attribute.prototype = Object.create( THREE.BufferAttribute.prototype ); + for (var y = 0; y <= heightSegments; y++) { + var indexRow = []; + var v = y / heightSegments; // calculate the radius of the current row -THREE.Uint8ClampedAttribute = function ( size, itemSize ) { + var radius = v * (radiusBottom - radiusTop) + radiusTop; - this.array = new Uint8ClampedArray( size * itemSize ); - this.itemSize = itemSize; + for (var x = 0; x <= radialSegments; x++) { + var u = x / radialSegments; + var theta = u * thetaLength + thetaStart; + var sinTheta = Math.sin(theta); + var cosTheta = Math.cos(theta); // vertex -}; + vertex.x = radius * sinTheta; + vertex.y = -v * height + halfHeight; + vertex.z = radius * cosTheta; + vertices.push(vertex.x, vertex.y, vertex.z); // normal -THREE.Uint8ClampedAttribute.prototype = Object.create( THREE.BufferAttribute.prototype ); + normal.set(sinTheta, slope, cosTheta).normalize(); + normals.push(normal.x, normal.y, normal.z); // uv -THREE.Int16Attribute = function ( size, itemSize ) { + uvs.push(u, 1 - v); // save index of vertex in respective row - this.array = new Int16Array( size * itemSize ); - this.itemSize = itemSize; + indexRow.push(index++); + } // now save vertices of the row in our index array -}; -THREE.Int16Attribute.prototype = Object.create( THREE.BufferAttribute.prototype ); + indexArray.push(indexRow); + } // generate indices -THREE.Uint16Attribute = function ( size, itemSize ) { - this.array = new Uint16Array( size * itemSize ); - this.itemSize = itemSize; + for (var _x = 0; _x < radialSegments; _x++) { + for (var _y = 0; _y < heightSegments; _y++) { + // we use the index array to access the correct indices + var a = indexArray[_y][_x]; + var b = indexArray[_y + 1][_x]; + var c = indexArray[_y + 1][_x + 1]; + var d = indexArray[_y][_x + 1]; // faces -}; + indices.push(a, b, d); + indices.push(b, c, d); // update group counter -THREE.Uint16Attribute.prototype = Object.create( THREE.BufferAttribute.prototype ); + groupCount += 6; + } + } // add a group to the geometry. this will ensure multi material support -THREE.Int32Attribute = function ( size, itemSize ) { - this.array = new Int32Array( size * itemSize ); - this.itemSize = itemSize; + scope.addGroup(groupStart, groupCount, 0); // calculate new start value for groups -}; + groupStart += groupCount; + } -THREE.Int32Attribute.prototype = Object.create( THREE.BufferAttribute.prototype ); + function generateCap(top) { + // save the index of the first center vertex + var centerIndexStart = index; + var uv = new Vector2(); + var vertex = new Vector3(); + var groupCount = 0; + var radius = top === true ? radiusTop : radiusBottom; + var sign = top === true ? 1 : -1; // first we generate the center vertex data of the cap. + // because the geometry needs one set of uvs per face, + // we must generate a center vertex per face/segment -THREE.Uint32Attribute = function ( size, itemSize ) { + for (var x = 1; x <= radialSegments; x++) { + // vertex + vertices.push(0, halfHeight * sign, 0); // normal - this.array = new Uint32Array( size * itemSize ); - this.itemSize = itemSize; + normals.push(0, sign, 0); // uv -}; + uvs.push(0.5, 0.5); // increase index -THREE.Uint32Attribute.prototype = Object.create( THREE.BufferAttribute.prototype ); + index++; + } // save the index of the last center vertex -THREE.Float32Attribute = function ( size, itemSize ) { - this.array = new Float32Array( size * itemSize ); - this.itemSize = itemSize; + var centerIndexEnd = index; // now we generate the surrounding vertices, normals and uvs -}; + for (var _x2 = 0; _x2 <= radialSegments; _x2++) { + var u = _x2 / radialSegments; + var theta = u * thetaLength + thetaStart; + var cosTheta = Math.cos(theta); + var sinTheta = Math.sin(theta); // vertex -THREE.Float32Attribute.prototype = Object.create( THREE.BufferAttribute.prototype ); + vertex.x = radius * sinTheta; + vertex.y = halfHeight * sign; + vertex.z = radius * cosTheta; + vertices.push(vertex.x, vertex.y, vertex.z); // normal -THREE.Float64Attribute = function ( size, itemSize ) { + normals.push(0, sign, 0); // uv - this.array = new Float64Array( size * itemSize ); - this.itemSize = itemSize; + uv.x = cosTheta * 0.5 + 0.5; + uv.y = sinTheta * 0.5 * sign + 0.5; + uvs.push(uv.x, uv.y); // increase index -}; + index++; + } // generate indices -THREE.Float64Attribute.prototype = Object.create( THREE.BufferAttribute.prototype ); -/** - * @author alteredq / http://alteredqualia.com/ - */ -THREE.BufferGeometry = function () { + for (var _x3 = 0; _x3 < radialSegments; _x3++) { + var c = centerIndexStart + _x3; + var i = centerIndexEnd + _x3; - this.id = THREE.GeometryIdCount ++; - this.uuid = THREE.Math.generateUUID(); + if (top === true) { + // face top + indices.push(i, i + 1, c); + } else { + // face bottom + indices.push(i + 1, i, c); + } - this.name = ''; + groupCount += 3; + } // add a group to the geometry. this will ensure multi material support - this.attributes = {}; - this.drawcalls = []; - this.offsets = this.drawcalls; // backwards compatibility - this.boundingBox = null; - this.boundingSphere = null; + scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); // calculate new start value for groups -}; + groupStart += groupCount; + } -THREE.BufferGeometry.prototype = { + return _this; + } - constructor: THREE.BufferGeometry, + return CylinderBufferGeometry; + }(BufferGeometry); - addAttribute: function ( name, attribute ) { + var CylinderGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(CylinderGeometry, _Geometry); - if ( attribute instanceof THREE.BufferAttribute === false ) { + function CylinderGeometry(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) { + var _this; - console.warn( 'DEPRECATED: BufferGeometry\'s addAttribute() now expects ( name, attribute ).' ); + _this = _Geometry.call(this) || this; + _this.type = 'CylinderGeometry'; + _this.parameters = { + radiusTop: radiusTop, + radiusBottom: radiusBottom, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - this.attributes[ name ] = { array: arguments[ 1 ], itemSize: arguments[ 2 ] }; + _this.fromBufferGeometry(new CylinderBufferGeometry(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength)); - return; + _this.mergeVertices(); + return _this; } - this.attributes[ name ] = attribute; + return CylinderGeometry; + }(Geometry); - }, + var ConeGeometry = /*#__PURE__*/function (_CylinderGeometry) { + _inheritsLoose(ConeGeometry, _CylinderGeometry); - getAttribute: function ( name ) { + function ConeGeometry(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) { + var _this; - return this.attributes[ name ]; + _this = _CylinderGeometry.call(this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) || this; + _this.type = 'ConeGeometry'; + _this.parameters = { + radius: radius, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + return _this; + } - }, + return ConeGeometry; + }(CylinderGeometry); - addDrawCall: function ( start, count, indexOffset ) { + var ConeBufferGeometry = /*#__PURE__*/function (_CylinderBufferGeomet) { + _inheritsLoose(ConeBufferGeometry, _CylinderBufferGeomet); - this.drawcalls.push( { + function ConeBufferGeometry(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) { + var _this; - start: start, - count: count, - index: indexOffset !== undefined ? indexOffset : 0 + _this = _CylinderBufferGeomet.call(this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) || this; + _this.type = 'ConeBufferGeometry'; + _this.parameters = { + radius: radius, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + return _this; + } - } ); + return ConeBufferGeometry; + }(CylinderBufferGeometry); - }, + var PolyhedronBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(PolyhedronBufferGeometry, _BufferGeometry); - applyMatrix: function ( matrix ) { + function PolyhedronBufferGeometry(vertices, indices, radius, detail) { + var _this; - var position = this.attributes.position; + _this = _BufferGeometry.call(this) || this; + _this.type = 'PolyhedronBufferGeometry'; + _this.parameters = { + vertices: vertices, + indices: indices, + radius: radius, + detail: detail + }; + radius = radius || 1; + detail = detail || 0; // default buffer data - if ( position !== undefined ) { + var vertexBuffer = []; + var uvBuffer = []; // the subdivision creates the vertex buffer data - matrix.applyToVector3Array( position.array ); - position.needsUpdate = true; + subdivide(detail); // all vertices should lie on a conceptual sphere with a given radius - } + applyRadius(radius); // finally, create the uv data - var normal = this.attributes.normal; + generateUVs(); // build non-indexed geometry - if ( normal !== undefined ) { + _this.setAttribute('position', new Float32BufferAttribute(vertexBuffer, 3)); - var normalMatrix = new THREE.Matrix3().getNormalMatrix( matrix ); + _this.setAttribute('normal', new Float32BufferAttribute(vertexBuffer.slice(), 3)); - normalMatrix.applyToVector3Array( normal.array ); - normal.needsUpdate = true; + _this.setAttribute('uv', new Float32BufferAttribute(uvBuffer, 2)); - } + if (detail === 0) { + _this.computeVertexNormals(); // flat normals - }, + } else { + _this.normalizeNormals(); // smooth normals - computeBoundingBox: function () { + } // helper functions - if ( this.boundingBox === null ) { - this.boundingBox = new THREE.Box3(); + function subdivide(detail) { + var a = new Vector3(); + var b = new Vector3(); + var c = new Vector3(); // iterate over all faces and apply a subdivison with the given detail value - } + for (var i = 0; i < indices.length; i += 3) { + // get the vertices of the face + getVertexByIndex(indices[i + 0], a); + getVertexByIndex(indices[i + 1], b); + getVertexByIndex(indices[i + 2], c); // perform subdivision - var positions = this.attributes[ "position" ].array; + subdivideFace(a, b, c, detail); + } + } - if ( positions ) { + function subdivideFace(a, b, c, detail) { + var cols = detail + 1; // we use this multidimensional array as a data structure for creating the subdivision - var bb = this.boundingBox; + var v = []; // construct all of the vertices for this subdivision - if( positions.length >= 3 ) { - bb.min.x = bb.max.x = positions[ 0 ]; - bb.min.y = bb.max.y = positions[ 1 ]; - bb.min.z = bb.max.z = positions[ 2 ]; - } + for (var i = 0; i <= cols; i++) { + v[i] = []; + var aj = a.clone().lerp(c, i / cols); + var bj = b.clone().lerp(c, i / cols); + var rows = cols - i; - for ( var i = 3, il = positions.length; i < il; i += 3 ) { + for (var j = 0; j <= rows; j++) { + if (j === 0 && i === cols) { + v[i][j] = aj; + } else { + v[i][j] = aj.clone().lerp(bj, j / rows); + } + } + } // construct all of the faces - var x = positions[ i ]; - var y = positions[ i + 1 ]; - var z = positions[ i + 2 ]; - // bounding box + for (var _i = 0; _i < cols; _i++) { + for (var _j = 0; _j < 2 * (cols - _i) - 1; _j++) { + var k = Math.floor(_j / 2); - if ( x < bb.min.x ) { + if (_j % 2 === 0) { + pushVertex(v[_i][k + 1]); + pushVertex(v[_i + 1][k]); + pushVertex(v[_i][k]); + } else { + pushVertex(v[_i][k + 1]); + pushVertex(v[_i + 1][k + 1]); + pushVertex(v[_i + 1][k]); + } + } + } + } - bb.min.x = x; + function applyRadius(radius) { + var vertex = new Vector3(); // iterate over the entire buffer and apply the radius to each vertex - } else if ( x > bb.max.x ) { + for (var i = 0; i < vertexBuffer.length; i += 3) { + vertex.x = vertexBuffer[i + 0]; + vertex.y = vertexBuffer[i + 1]; + vertex.z = vertexBuffer[i + 2]; + vertex.normalize().multiplyScalar(radius); + vertexBuffer[i + 0] = vertex.x; + vertexBuffer[i + 1] = vertex.y; + vertexBuffer[i + 2] = vertex.z; + } + } - bb.max.x = x; + function generateUVs() { + var vertex = new Vector3(); + for (var i = 0; i < vertexBuffer.length; i += 3) { + vertex.x = vertexBuffer[i + 0]; + vertex.y = vertexBuffer[i + 1]; + vertex.z = vertexBuffer[i + 2]; + var u = azimuth(vertex) / 2 / Math.PI + 0.5; + var v = inclination(vertex) / Math.PI + 0.5; + uvBuffer.push(u, 1 - v); } - if ( y < bb.min.y ) { - - bb.min.y = y; + correctUVs(); + correctSeam(); + } - } else if ( y > bb.max.y ) { + function correctSeam() { + // handle case when face straddles the seam, see #3269 + for (var i = 0; i < uvBuffer.length; i += 6) { + // uv data of a single face + var x0 = uvBuffer[i + 0]; + var x1 = uvBuffer[i + 2]; + var x2 = uvBuffer[i + 4]; + var max = Math.max(x0, x1, x2); + var min = Math.min(x0, x1, x2); // 0.9 is somewhat arbitrary - bb.max.y = y; + if (max > 0.9 && min < 0.1) { + if (x0 < 0.2) uvBuffer[i + 0] += 1; + if (x1 < 0.2) uvBuffer[i + 2] += 1; + if (x2 < 0.2) uvBuffer[i + 4] += 1; + } + } + } + function pushVertex(vertex) { + vertexBuffer.push(vertex.x, vertex.y, vertex.z); + } + + function getVertexByIndex(index, vertex) { + var stride = index * 3; + vertex.x = vertices[stride + 0]; + vertex.y = vertices[stride + 1]; + vertex.z = vertices[stride + 2]; + } + + function correctUVs() { + var a = new Vector3(); + var b = new Vector3(); + var c = new Vector3(); + var centroid = new Vector3(); + var uvA = new Vector2(); + var uvB = new Vector2(); + var uvC = new Vector2(); + + for (var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6) { + a.set(vertexBuffer[i + 0], vertexBuffer[i + 1], vertexBuffer[i + 2]); + b.set(vertexBuffer[i + 3], vertexBuffer[i + 4], vertexBuffer[i + 5]); + c.set(vertexBuffer[i + 6], vertexBuffer[i + 7], vertexBuffer[i + 8]); + uvA.set(uvBuffer[j + 0], uvBuffer[j + 1]); + uvB.set(uvBuffer[j + 2], uvBuffer[j + 3]); + uvC.set(uvBuffer[j + 4], uvBuffer[j + 5]); + centroid.copy(a).add(b).add(c).divideScalar(3); + var azi = azimuth(centroid); + correctUV(uvA, j + 0, a, azi); + correctUV(uvB, j + 2, b, azi); + correctUV(uvC, j + 4, c, azi); } + } - if ( z < bb.min.z ) { + function correctUV(uv, stride, vector, azimuth) { + if (azimuth < 0 && uv.x === 1) { + uvBuffer[stride] = uv.x - 1; + } - bb.min.z = z; + if (vector.x === 0 && vector.z === 0) { + uvBuffer[stride] = azimuth / 2 / Math.PI + 0.5; + } + } // Angle around the Y axis, counter-clockwise when looking from above. - } else if ( z > bb.max.z ) { - bb.max.z = z; + function azimuth(vector) { + return Math.atan2(vector.z, -vector.x); + } // Angle above the XZ plane. - } + function inclination(vector) { + return Math.atan2(-vector.y, Math.sqrt(vector.x * vector.x + vector.z * vector.z)); } + return _this; } - if ( positions === undefined || positions.length === 0 ) { + return PolyhedronBufferGeometry; + }(BufferGeometry); - this.boundingBox.min.set( 0, 0, 0 ); - this.boundingBox.max.set( 0, 0, 0 ); + var DodecahedronBufferGeometry = /*#__PURE__*/function (_PolyhedronBufferGeom) { + _inheritsLoose(DodecahedronBufferGeometry, _PolyhedronBufferGeom); + function DodecahedronBufferGeometry(radius, detail) { + var _this; + + var t = (1 + Math.sqrt(5)) / 2; + var r = 1 / t; + var vertices = [// (±1, ±1, ±1) + -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, // (0, ±1/φ, ±φ) + 0, -r, -t, 0, -r, t, 0, r, -t, 0, r, t, // (±1/φ, ±φ, 0) + -r, -t, 0, -r, t, 0, r, -t, 0, r, t, 0, // (±φ, 0, ±1/φ) + -t, 0, -r, t, 0, -r, -t, 0, r, t, 0, r]; + var indices = [3, 11, 7, 3, 7, 15, 3, 15, 13, 7, 19, 17, 7, 17, 6, 7, 6, 15, 17, 4, 8, 17, 8, 10, 17, 10, 6, 8, 0, 16, 8, 16, 2, 8, 2, 10, 0, 12, 1, 0, 1, 18, 0, 18, 16, 6, 10, 2, 6, 2, 13, 6, 13, 15, 2, 16, 18, 2, 18, 3, 2, 3, 13, 18, 1, 9, 18, 9, 11, 18, 11, 3, 4, 14, 12, 4, 12, 0, 4, 0, 8, 11, 9, 5, 11, 5, 19, 11, 19, 7, 19, 5, 14, 19, 14, 4, 19, 4, 17, 1, 12, 14, 1, 14, 5, 1, 5, 9]; + _this = _PolyhedronBufferGeom.call(this, vertices, indices, radius, detail) || this; + _this.type = 'DodecahedronBufferGeometry'; + _this.parameters = { + radius: radius, + detail: detail + }; + return _this; } - }, + return DodecahedronBufferGeometry; + }(PolyhedronBufferGeometry); - computeBoundingSphere: function () { + var DodecahedronGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(DodecahedronGeometry, _Geometry); - var box = new THREE.Box3(); - var vector = new THREE.Vector3(); + function DodecahedronGeometry(radius, detail) { + var _this; - return function () { + _this = _Geometry.call(this) || this; + _this.type = 'DodecahedronGeometry'; + _this.parameters = { + radius: radius, + detail: detail + }; - if ( this.boundingSphere === null ) { + _this.fromBufferGeometry(new DodecahedronBufferGeometry(radius, detail)); - this.boundingSphere = new THREE.Sphere(); + _this.mergeVertices(); - } + return _this; + } - var positions = this.attributes[ "position" ].array; + return DodecahedronGeometry; + }(Geometry); - if ( positions ) { + var _v0$2 = new Vector3(); - box.makeEmpty(); + var _v1$5 = new Vector3(); - var center = this.boundingSphere.center; + var _normal$1 = new Vector3(); - for ( var i = 0, il = positions.length; i < il; i += 3 ) { + var _triangle = new Triangle(); - vector.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ); - box.addPoint( vector ); + var EdgesGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(EdgesGeometry, _BufferGeometry); + function EdgesGeometry(geometry, thresholdAngle) { + var _this; + + _this = _BufferGeometry.call(this) || this; + _this.type = 'EdgesGeometry'; + _this.parameters = { + thresholdAngle: thresholdAngle + }; + thresholdAngle = thresholdAngle !== undefined ? thresholdAngle : 1; + + if (geometry.isGeometry) { + geometry = new BufferGeometry().fromGeometry(geometry); + } + + var precisionPoints = 4; + var precision = Math.pow(10, precisionPoints); + var thresholdDot = Math.cos(MathUtils.DEG2RAD * thresholdAngle); + var indexAttr = geometry.getIndex(); + var positionAttr = geometry.getAttribute('position'); + var indexCount = indexAttr ? indexAttr.count : positionAttr.count; + var indexArr = [0, 0, 0]; + var vertKeys = ['a', 'b', 'c']; + var hashes = new Array(3); + var edgeData = {}; + var vertices = []; + + for (var i = 0; i < indexCount; i += 3) { + if (indexAttr) { + indexArr[0] = indexAttr.getX(i); + indexArr[1] = indexAttr.getX(i + 1); + indexArr[2] = indexAttr.getX(i + 2); + } else { + indexArr[0] = i; + indexArr[1] = i + 1; + indexArr[2] = i + 2; } - box.center( center ); + var a = _triangle.a, + b = _triangle.b, + c = _triangle.c; + a.fromBufferAttribute(positionAttr, indexArr[0]); + b.fromBufferAttribute(positionAttr, indexArr[1]); + c.fromBufferAttribute(positionAttr, indexArr[2]); - // hoping to find a boundingSphere with a radius smaller than the - // boundingSphere of the boundingBox: sqrt(3) smaller in the best case + _triangle.getNormal(_normal$1); // create hashes for the edge from the vertices - var maxRadiusSq = 0; - for ( var i = 0, il = positions.length; i < il; i += 3 ) { + hashes[0] = Math.round(a.x * precision) + "," + Math.round(a.y * precision) + "," + Math.round(a.z * precision); + hashes[1] = Math.round(b.x * precision) + "," + Math.round(b.y * precision) + "," + Math.round(b.z * precision); + hashes[2] = Math.round(c.x * precision) + "," + Math.round(c.y * precision) + "," + Math.round(c.z * precision); // skip degenerate triangles - vector.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ); - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) ); + if (hashes[0] === hashes[1] || hashes[1] === hashes[2] || hashes[2] === hashes[0]) { + continue; + } // iterate over every edge + + + for (var j = 0; j < 3; j++) { + // get the first and next vertex making up the edge + var jNext = (j + 1) % 3; + var vecHash0 = hashes[j]; + var vecHash1 = hashes[jNext]; + var v0 = _triangle[vertKeys[j]]; + var v1 = _triangle[vertKeys[jNext]]; + var hash = vecHash0 + "_" + vecHash1; + var reverseHash = vecHash1 + "_" + vecHash0; + + if (reverseHash in edgeData && edgeData[reverseHash]) { + // if we found a sibling edge add it into the vertex array if + // it meets the angle threshold and delete the edge from the map. + if (_normal$1.dot(edgeData[reverseHash].normal) <= thresholdDot) { + vertices.push(v0.x, v0.y, v0.z); + vertices.push(v1.x, v1.y, v1.z); + } + edgeData[reverseHash] = null; + } else if (!(hash in edgeData)) { + // if we've already got an edge here then skip adding a new one + edgeData[hash] = { + index0: indexArr[j], + index1: indexArr[jNext], + normal: _normal$1.clone() + }; + } } + } // iterate over all remaining, unmatched edges and add them to the vertex array - this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); - } + for (var key in edgeData) { + if (edgeData[key]) { + var _edgeData$key = edgeData[key], + index0 = _edgeData$key.index0, + index1 = _edgeData$key.index1; - } + _v0$2.fromBufferAttribute(positionAttr, index0); - }(), + _v1$5.fromBufferAttribute(positionAttr, index1); - computeFaceNormals: function () { + vertices.push(_v0$2.x, _v0$2.y, _v0$2.z); + vertices.push(_v1$5.x, _v1$5.y, _v1$5.z); + } + } - // backwards compatibility + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - }, + return _this; + } - computeVertexNormals: function () { + return EdgesGeometry; + }(BufferGeometry); - if ( this.attributes[ "position" ] ) { + /** + * Port from https://github.com/mapbox/earcut (v2.2.2) + */ + var Earcut = { + triangulate: function triangulate(data, holeIndices, dim) { + dim = dim || 2; + var hasHoles = holeIndices && holeIndices.length; + var outerLen = hasHoles ? holeIndices[0] * dim : data.length; + var outerNode = linkedList(data, 0, outerLen, dim, true); + var triangles = []; + if (!outerNode || outerNode.next === outerNode.prev) return triangles; + var minX, minY, maxX, maxY, x, y, invSize; + if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox - var i, il; - var j, jl; + if (data.length > 80 * dim) { + minX = maxX = data[0]; + minY = maxY = data[1]; - var nVertexElements = this.attributes[ "position" ].array.length; + for (var i = dim; i < outerLen; i += dim) { + x = data[i]; + y = data[i + 1]; + if (x < minX) minX = x; + if (y < minY) minY = y; + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; + } // minX, minY and invSize are later used to transform coords into integers for z-order calculation - if ( this.attributes[ "normal" ] === undefined ) { - this.attributes[ "normal" ] = { + invSize = Math.max(maxX - minX, maxY - minY); + invSize = invSize !== 0 ? 1 / invSize : 0; + } - itemSize: 3, - array: new Float32Array( nVertexElements ) + earcutLinked(outerNode, triangles, dim, minX, minY, invSize); + return triangles; + } + }; // create a circular doubly linked list from polygon points in the specified winding order - }; + function linkedList(data, start, end, dim, clockwise) { + var i, last; - } else { + if (clockwise === signedArea(data, start, end, dim) > 0) { + for (i = start; i < end; i += dim) { + last = insertNode(i, data[i], data[i + 1], last); + } + } else { + for (i = end - dim; i >= start; i -= dim) { + last = insertNode(i, data[i], data[i + 1], last); + } + } + + if (last && equals(last, last.next)) { + removeNode(last); + last = last.next; + } - // reset existing normals to zero + return last; + } // eliminate colinear or duplicate points - for ( i = 0, il = this.attributes[ "normal" ].array.length; i < il; i ++ ) { - this.attributes[ "normal" ].array[ i ] = 0; + function filterPoints(start, end) { + if (!start) return start; + if (!end) end = start; + var p = start, + again; - } + do { + again = false; + if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { + removeNode(p); + p = end = p.prev; + if (p === p.next) break; + again = true; + } else { + p = p.next; } + } while (again || p !== end); - var positions = this.attributes[ "position" ].array; - var normals = this.attributes[ "normal" ].array; + return end; + } // main ear slicing loop which triangulates a polygon (given as a linked list) - var vA, vB, vC, x, y, z, - pA = new THREE.Vector3(), - pB = new THREE.Vector3(), - pC = new THREE.Vector3(), + function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { + if (!ear) return; // interlink polygon nodes in z-order - cb = new THREE.Vector3(), - ab = new THREE.Vector3(); + if (!pass && invSize) indexCurve(ear, minX, minY, invSize); + var stop = ear, + prev, + next; // iterate through ears, slicing them one by one - // indexed elements + while (ear.prev !== ear.next) { + prev = ear.prev; + next = ear.next; - if ( this.attributes[ "index" ] ) { + if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { + // cut off the triangle + triangles.push(prev.i / dim); + triangles.push(ear.i / dim); + triangles.push(next.i / dim); + removeNode(ear); // skipping the next vertex leads to less sliver triangles - var indices = this.attributes[ "index" ].array; + ear = next.next; + stop = next.next; + continue; + } - var offsets = (this.offsets.length > 0 ? this.offsets : [ { start: 0, count: indices.length, index: 0 } ]); + ear = next; // if we looped through the whole remaining polygon and can't find any more ears - for ( j = 0, jl = offsets.length; j < jl; ++ j ) { + if (ear === stop) { + // try filtering points and slicing again + if (!pass) { + earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); // if this didn't work, try curing all small self-intersections locally + } else if (pass === 1) { + ear = cureLocalIntersections(filterPoints(ear), triangles, dim); + earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); // as a last resort, try splitting the remaining polygon into two + } else if (pass === 2) { + splitEarcut(ear, triangles, dim, minX, minY, invSize); + } - var start = offsets[ j ].start; - var count = offsets[ j ].count; - var index = offsets[ j ].index; + break; + } + } + } // check whether a polygon node forms a valid ear with adjacent nodes - for ( i = start, il = start + count; i < il; i += 3 ) { - vA = index + indices[ i ]; - vB = index + indices[ i + 1 ]; - vC = index + indices[ i + 2 ]; + function isEar(ear) { + var a = ear.prev, + b = ear, + c = ear.next; + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + // now make sure we don't have other points inside the potential ear - x = positions[ vA * 3 ]; - y = positions[ vA * 3 + 1 ]; - z = positions[ vA * 3 + 2 ]; - pA.set( x, y, z ); + var p = ear.next.next; - x = positions[ vB * 3 ]; - y = positions[ vB * 3 + 1 ]; - z = positions[ vB * 3 + 2 ]; - pB.set( x, y, z ); + while (p !== ear.prev) { + if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; + p = p.next; + } - x = positions[ vC * 3 ]; - y = positions[ vC * 3 + 1 ]; - z = positions[ vC * 3 + 2 ]; - pC.set( x, y, z ); + return true; + } - cb.subVectors( pC, pB ); - ab.subVectors( pA, pB ); - cb.cross( ab ); + function isEarHashed(ear, minX, minY, invSize) { + var a = ear.prev, + b = ear, + c = ear.next; + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + // triangle bbox; min & max are calculated like this for speed - normals[ vA * 3 ] += cb.x; - normals[ vA * 3 + 1 ] += cb.y; - normals[ vA * 3 + 2 ] += cb.z; + var minTX = a.x < b.x ? a.x < c.x ? a.x : c.x : b.x < c.x ? b.x : c.x, + minTY = a.y < b.y ? a.y < c.y ? a.y : c.y : b.y < c.y ? b.y : c.y, + maxTX = a.x > b.x ? a.x > c.x ? a.x : c.x : b.x > c.x ? b.x : c.x, + maxTY = a.y > b.y ? a.y > c.y ? a.y : c.y : b.y > c.y ? b.y : c.y; // z-order range for the current triangle bbox; - normals[ vB * 3 ] += cb.x; - normals[ vB * 3 + 1 ] += cb.y; - normals[ vB * 3 + 2 ] += cb.z; + var minZ = zOrder(minTX, minTY, minX, minY, invSize), + maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); + var p = ear.prevZ, + n = ear.nextZ; // look for points inside the triangle in both directions - normals[ vC * 3 ] += cb.x; - normals[ vC * 3 + 1 ] += cb.y; - normals[ vC * 3 + 2 ] += cb.z; + while (p && p.z >= minZ && n && n.z <= maxZ) { + if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; + p = p.prevZ; + if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; + n = n.nextZ; + } // look for remaining points in decreasing z-order - } - } + while (p && p.z >= minZ) { + if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; + p = p.prevZ; + } // look for remaining points in increasing z-order - // non-indexed elements (unconnected triangle soup) - } else { + while (n && n.z <= maxZ) { + if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; + n = n.nextZ; + } - for ( i = 0, il = positions.length; i < il; i += 9 ) { + return true; + } // go through all polygon nodes and cure small local self-intersections - x = positions[ i ]; - y = positions[ i + 1 ]; - z = positions[ i + 2 ]; - pA.set( x, y, z ); - x = positions[ i + 3 ]; - y = positions[ i + 4 ]; - z = positions[ i + 5 ]; - pB.set( x, y, z ); + function cureLocalIntersections(start, triangles, dim) { + var p = start; - x = positions[ i + 6 ]; - y = positions[ i + 7 ]; - z = positions[ i + 8 ]; - pC.set( x, y, z ); + do { + var a = p.prev, + b = p.next.next; - cb.subVectors( pC, pB ); - ab.subVectors( pA, pB ); - cb.cross( ab ); + if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { + triangles.push(a.i / dim); + triangles.push(p.i / dim); + triangles.push(b.i / dim); // remove two nodes involved - normals[ i ] = cb.x; - normals[ i + 1 ] = cb.y; - normals[ i + 2 ] = cb.z; + removeNode(p); + removeNode(p.next); + p = start = b; + } - normals[ i + 3 ] = cb.x; - normals[ i + 4 ] = cb.y; - normals[ i + 5 ] = cb.z; + p = p.next; + } while (p !== start); - normals[ i + 6 ] = cb.x; - normals[ i + 7 ] = cb.y; - normals[ i + 8 ] = cb.z; + return filterPoints(p); + } // try splitting polygon into two and triangulate them independently - } - } + function splitEarcut(start, triangles, dim, minX, minY, invSize) { + // look for a valid diagonal that divides the polygon into two + var a = start; - this.normalizeNormals(); + do { + var b = a.next.next; - this.normalsNeedUpdate = true; + while (b !== a.prev) { + if (a.i !== b.i && isValidDiagonal(a, b)) { + // split the polygon in two by the diagonal + var c = splitPolygon(a, b); // filter colinear points around the cuts - } + a = filterPoints(a, a.next); + c = filterPoints(c, c.next); // run earcut on each half - }, + earcutLinked(a, triangles, dim, minX, minY, invSize); + earcutLinked(c, triangles, dim, minX, minY, invSize); + return; + } - computeTangents: function () { + b = b.next; + } - // based on http://www.terathon.com/code/tangent.html - // (per vertex tangents) + a = a.next; + } while (a !== start); + } // link every hole into the outer loop, producing a single-ring polygon without holes - if ( this.attributes[ "index" ] === undefined || - this.attributes[ "position" ] === undefined || - this.attributes[ "normal" ] === undefined || - this.attributes[ "uv" ] === undefined ) { - console.warn( "Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()" ); - return; + function eliminateHoles(data, holeIndices, outerNode, dim) { + var queue = []; + var i, len, start, end, list; + for (i = 0, len = holeIndices.length; i < len; i++) { + start = holeIndices[i] * dim; + end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + list = linkedList(data, start, end, dim, false); + if (list === list.next) list.steiner = true; + queue.push(getLeftmost(list)); } - var indices = this.attributes[ "index" ].array; - var positions = this.attributes[ "position" ].array; - var normals = this.attributes[ "normal" ].array; - var uvs = this.attributes[ "uv" ].array; + queue.sort(compareX); // process holes from left to right - var nVertices = positions.length / 3; + for (i = 0; i < queue.length; i++) { + eliminateHole(queue[i], outerNode); + outerNode = filterPoints(outerNode, outerNode.next); + } - if ( this.attributes[ "tangent" ] === undefined ) { + return outerNode; + } - var nTangentElements = 4 * nVertices; + function compareX(a, b) { + return a.x - b.x; + } // find a bridge between vertices that connects hole with an outer ring and and link it - this.attributes[ "tangent" ] = { - itemSize: 4, - array: new Float32Array( nTangentElements ) + function eliminateHole(hole, outerNode) { + outerNode = findHoleBridge(hole, outerNode); - }; + if (outerNode) { + var b = splitPolygon(outerNode, hole); // filter collinear points around the cuts + filterPoints(outerNode, outerNode.next); + filterPoints(b, b.next); } + } // David Eberly's algorithm for finding a bridge between hole and outer polygon - var tangents = this.attributes[ "tangent" ].array; - var tan1 = [], tan2 = []; + function findHoleBridge(hole, outerNode) { + var p = outerNode; + var hx = hole.x; + var hy = hole.y; + var qx = -Infinity, + m; // find a segment intersected by a ray from the hole's leftmost point to the left; + // segment's endpoint with lesser x will be potential connection point - for ( var k = 0; k < nVertices; k ++ ) { + do { + if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { + var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); - tan1[ k ] = new THREE.Vector3(); - tan2[ k ] = new THREE.Vector3(); - - } + if (x <= hx && x > qx) { + qx = x; - var xA, yA, zA, - xB, yB, zB, - xC, yC, zC, + if (x === hx) { + if (hy === p.y) return p; + if (hy === p.next.y) return p.next; + } - uA, vA, - uB, vB, - uC, vC, + m = p.x < p.next.x ? p : p.next; + } + } - x1, x2, y1, y2, z1, z2, - s1, s2, t1, t2, r; + p = p.next; + } while (p !== outerNode); - var sdir = new THREE.Vector3(), tdir = new THREE.Vector3(); + if (!m) return null; + if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint + // look for points inside the triangle of hole point, segment intersection and endpoint; + // if there are no points found, we have a valid connection; + // otherwise choose the point of the minimum angle with the ray as connection point - function handleTriangle( a, b, c ) { + var stop = m, + mx = m.x, + my = m.y; + var tanMin = Infinity, + tan; + p = m; - xA = positions[ a * 3 ]; - yA = positions[ a * 3 + 1 ]; - zA = positions[ a * 3 + 2 ]; + do { + if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { + tan = Math.abs(hy - p.y) / (hx - p.x); // tangential - xB = positions[ b * 3 ]; - yB = positions[ b * 3 + 1 ]; - zB = positions[ b * 3 + 2 ]; + if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) { + m = p; + tanMin = tan; + } + } - xC = positions[ c * 3 ]; - yC = positions[ c * 3 + 1 ]; - zC = positions[ c * 3 + 2 ]; + p = p.next; + } while (p !== stop); - uA = uvs[ a * 2 ]; - vA = uvs[ a * 2 + 1 ]; + return m; + } // whether sector in vertex m contains sector in vertex p in the same coordinates - uB = uvs[ b * 2 ]; - vB = uvs[ b * 2 + 1 ]; - uC = uvs[ c * 2 ]; - vC = uvs[ c * 2 + 1 ]; + function sectorContainsSector(m, p) { + return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0; + } // interlink polygon nodes in z-order - x1 = xB - xA; - x2 = xC - xA; - y1 = yB - yA; - y2 = yC - yA; + function indexCurve(start, minX, minY, invSize) { + var p = start; - z1 = zB - zA; - z2 = zC - zA; + do { + if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize); + p.prevZ = p.prev; + p.nextZ = p.next; + p = p.next; + } while (p !== start); - s1 = uB - uA; - s2 = uC - uA; + p.prevZ.nextZ = null; + p.prevZ = null; + sortLinked(p); + } // Simon Tatham's linked list merge sort algorithm + // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html - t1 = vB - vA; - t2 = vC - vA; - r = 1.0 / ( s1 * t2 - s2 * t1 ); + function sortLinked(list) { + var i, + p, + q, + e, + tail, + numMerges, + pSize, + qSize, + inSize = 1; - sdir.set( - ( t2 * x1 - t1 * x2 ) * r, - ( t2 * y1 - t1 * y2 ) * r, - ( t2 * z1 - t1 * z2 ) * r - ); + do { + p = list; + list = null; + tail = null; + numMerges = 0; - tdir.set( - ( s1 * x2 - s2 * x1 ) * r, - ( s1 * y2 - s2 * y1 ) * r, - ( s1 * z2 - s2 * z1 ) * r - ); + while (p) { + numMerges++; + q = p; + pSize = 0; - tan1[ a ].add( sdir ); - tan1[ b ].add( sdir ); - tan1[ c ].add( sdir ); + for (i = 0; i < inSize; i++) { + pSize++; + q = q.nextZ; + if (!q) break; + } - tan2[ a ].add( tdir ); - tan2[ b ].add( tdir ); - tan2[ c ].add( tdir ); + qSize = inSize; - } + while (pSize > 0 || qSize > 0 && q) { + if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { + e = p; + p = p.nextZ; + pSize--; + } else { + e = q; + q = q.nextZ; + qSize--; + } - var i, il; - var j, jl; - var iA, iB, iC; + if (tail) tail.nextZ = e;else list = e; + e.prevZ = tail; + tail = e; + } - var offsets = this.offsets; + p = q; + } - for ( j = 0, jl = offsets.length; j < jl; ++ j ) { + tail.nextZ = null; + inSize *= 2; + } while (numMerges > 1); - var start = offsets[ j ].start; - var count = offsets[ j ].count; - var index = offsets[ j ].index; + return list; + } // z-order of a point given coords and inverse of the longer side of data bbox - for ( i = start, il = start + count; i < il; i += 3 ) { - iA = index + indices[ i ]; - iB = index + indices[ i + 1 ]; - iC = index + indices[ i + 2 ]; + function zOrder(x, y, minX, minY, invSize) { + // coords are transformed into non-negative 15-bit integer range + x = 32767 * (x - minX) * invSize; + y = 32767 * (y - minY) * invSize; + x = (x | x << 8) & 0x00FF00FF; + x = (x | x << 4) & 0x0F0F0F0F; + x = (x | x << 2) & 0x33333333; + x = (x | x << 1) & 0x55555555; + y = (y | y << 8) & 0x00FF00FF; + y = (y | y << 4) & 0x0F0F0F0F; + y = (y | y << 2) & 0x33333333; + y = (y | y << 1) & 0x55555555; + return x | y << 1; + } // find the leftmost node of a polygon ring - handleTriangle( iA, iB, iC ); - } + function getLeftmost(start) { + var p = start, + leftmost = start; - } + do { + if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p; + p = p.next; + } while (p !== start); - var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(); - var n = new THREE.Vector3(), n2 = new THREE.Vector3(); - var w, t, test; + return leftmost; + } // check if a point lies within a convex triangle - function handleVertex( v ) { - n.x = normals[ v * 3 ]; - n.y = normals[ v * 3 + 1 ]; - n.z = normals[ v * 3 + 2 ]; + function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { + return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; + } // check if a diagonal between two polygon nodes is valid (lies in polygon interior) - n2.copy( n ); - t = tan1[ v ]; + function isValidDiagonal(a, b) { + return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && ( // dones't intersect other edges + locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && ( // locally visible + area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors + equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case + } // signed area of a triangle - // Gram-Schmidt orthogonalize - tmp.copy( t ); - tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize(); + function area(p, q, r) { + return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); + } // check if two points are equal - // Calculate handedness - tmp2.crossVectors( n2, t ); - test = tmp2.dot( tan2[ v ] ); - w = ( test < 0.0 ) ? -1.0 : 1.0; + function equals(p1, p2) { + return p1.x === p2.x && p1.y === p2.y; + } // check if two segments intersect - tangents[ v * 4 ] = tmp.x; - tangents[ v * 4 + 1 ] = tmp.y; - tangents[ v * 4 + 2 ] = tmp.z; - tangents[ v * 4 + 3 ] = w; - } + function intersects(p1, q1, p2, q2) { + var o1 = sign(area(p1, q1, p2)); + var o2 = sign(area(p1, q1, q2)); + var o3 = sign(area(p2, q2, p1)); + var o4 = sign(area(p2, q2, q1)); + if (o1 !== o2 && o3 !== o4) return true; // general case - for ( j = 0, jl = offsets.length; j < jl; ++ j ) { + if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 - var start = offsets[ j ].start; - var count = offsets[ j ].count; - var index = offsets[ j ].index; + if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 - for ( i = start, il = start + count; i < il; i += 3 ) { + if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 - iA = index + indices[ i ]; - iB = index + indices[ i + 1 ]; - iC = index + indices[ i + 2 ]; + if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 - handleVertex( iA ); - handleVertex( iB ); - handleVertex( iC ); + return false; + } // for collinear points p, q, r, check if point q lies on segment pr - } - } + function onSegment(p, q, r) { + return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y); + } - }, + function sign(num) { + return num > 0 ? 1 : num < 0 ? -1 : 0; + } // check if a polygon diagonal intersects any polygon segments - /* - computeOffsets - Compute the draw offset for large models by chunking the index buffer into chunks of 65k addressable vertices. - This method will effectively rewrite the index buffer and remap all attributes to match the new indices. - WARNING: This method will also expand the vertex count to prevent sprawled triangles across draw offsets. - indexBufferSize - Defaults to 65535, but allows for larger or smaller chunks. - */ - computeOffsets: function(indexBufferSize) { - var size = indexBufferSize; - if(indexBufferSize === undefined) - size = 65535; //WebGL limits type of index buffer values to 16-bit. + function intersectsPolygon(a, b) { + var p = a; - var s = Date.now(); + do { + if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b)) return true; + p = p.next; + } while (p !== a); - var indices = this.attributes['index'].array; - var vertices = this.attributes['position'].array; + return false; + } // check if a polygon diagonal is locally inside the polygon - var verticesCount = (vertices.length/3); - var facesCount = (indices.length/3); - /* - console.log("Computing buffers in offsets of "+size+" -> indices:"+indices.length+" vertices:"+vertices.length); - console.log("Faces to process: "+(indices.length/3)); - console.log("Reordering "+verticesCount+" vertices."); - */ + function locallyInside(a, b) { + return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; + } // check if the middle point of a polygon diagonal is inside the polygon - var sortedIndices = new Uint16Array( indices.length ); //16-bit buffers - var indexPtr = 0; - var vertexPtr = 0; - var offsets = [ { start:0, count:0, index:0 } ]; - var offset = offsets[0]; + function middleInside(a, b) { + var p = a, + inside = false; + var px = (a.x + b.x) / 2, + py = (a.y + b.y) / 2; - var duplicatedVertices = 0; - var newVerticeMaps = 0; - var faceVertices = new Int32Array(6); - var vertexMap = new Int32Array( vertices.length ); - var revVertexMap = new Int32Array( vertices.length ); - for(var j = 0; j < vertices.length; j++) { vertexMap[j] = -1; revVertexMap[j] = -1; } + do { + if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x) inside = !inside; + p = p.next; + } while (p !== a); - /* - Traverse every face and reorder vertices in the proper offsets of 65k. - We can have more than 65k entries in the index buffer per offset, but only reference 65k values. - */ - for(var findex = 0; findex < facesCount; findex++) { - newVerticeMaps = 0; - - for(var vo = 0; vo < 3; vo++) { - var vid = indices[ findex*3 + vo ]; - if(vertexMap[vid] == -1) { - //Unmapped vertice - faceVertices[vo*2] = vid; - faceVertices[vo*2+1] = -1; - newVerticeMaps++; - } else if(vertexMap[vid] < offset.index) { - //Reused vertices from previous block (duplicate) - faceVertices[vo*2] = vid; - faceVertices[vo*2+1] = -1; - duplicatedVertices++; - } else { - //Reused vertice in the current block - faceVertices[vo*2] = vid; - faceVertices[vo*2+1] = vertexMap[vid]; - } - } + return inside; + } // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; + // if one belongs to the outer ring and another to a hole, it merges it into a single ring - var faceMax = vertexPtr + newVerticeMaps; - if(faceMax > (offset.index + size)) { - var new_offset = { start:indexPtr, count:0, index:vertexPtr }; - offsets.push(new_offset); - offset = new_offset; - //Re-evaluate reused vertices in light of new offset. - for(var v = 0; v < 6; v+=2) { - var new_vid = faceVertices[v+1]; - if(new_vid > -1 && new_vid < offset.index) - faceVertices[v+1] = -1; - } - } + function splitPolygon(a, b) { + var a2 = new Node(a.i, a.x, a.y), + b2 = new Node(b.i, b.x, b.y), + an = a.next, + bp = b.prev; + a.next = b; + b.prev = a; + a2.next = an; + an.prev = a2; + b2.next = a2; + a2.prev = b2; + bp.next = b2; + b2.prev = bp; + return b2; + } // create a node and optionally link it with previous one (in a circular doubly linked list) - //Reindex the face. - for(var v = 0; v < 6; v+=2) { - var vid = faceVertices[v]; - var new_vid = faceVertices[v+1]; - if(new_vid === -1) - new_vid = vertexPtr++; + function insertNode(i, x, y, last) { + var p = new Node(i, x, y); - vertexMap[vid] = new_vid; - revVertexMap[new_vid] = vid; - sortedIndices[indexPtr++] = new_vid - offset.index; //XXX overflows at 16bit - offset.count++; - } + if (!last) { + p.prev = p; + p.next = p; + } else { + p.next = last.next; + p.prev = last; + last.next.prev = p; + last.next = p; } - /* Move all attribute values to map to the new computed indices , also expand the vertice stack to match our new vertexPtr. */ - this.reorderBuffers(sortedIndices, revVertexMap, vertexPtr); - this.offsets = offsets; - - /* - var orderTime = Date.now(); - console.log("Reorder time: "+(orderTime-s)+"ms"); - console.log("Duplicated "+duplicatedVertices+" vertices."); - console.log("Compute Buffers time: "+(Date.now()-s)+"ms"); - console.log("Draw offsets: "+offsets.length); - */ - - return offsets; - }, - - merge: function () { - - console.log( 'BufferGeometry.merge(): TODO' ); + return p; + } - }, + function removeNode(p) { + p.next.prev = p.prev; + p.prev.next = p.next; + if (p.prevZ) p.prevZ.nextZ = p.nextZ; + if (p.nextZ) p.nextZ.prevZ = p.prevZ; + } - normalizeNormals: function () { + function Node(i, x, y) { + // vertex index in coordinates array + this.i = i; // vertex coordinates - var normals = this.attributes[ "normal" ].array; + this.x = x; + this.y = y; // previous and next vertex nodes in a polygon ring - var x, y, z, n; + this.prev = null; + this.next = null; // z-order curve value - for ( var i = 0, il = normals.length; i < il; i += 3 ) { + this.z = null; // previous and next nodes in z-order - x = normals[ i ]; - y = normals[ i + 1 ]; - z = normals[ i + 2 ]; + this.prevZ = null; + this.nextZ = null; // indicates whether this is a steiner point - n = 1.0 / Math.sqrt( x * x + y * y + z * z ); + this.steiner = false; + } - normals[ i ] *= n; - normals[ i + 1 ] *= n; - normals[ i + 2 ] *= n; + function signedArea(data, start, end, dim) { + var sum = 0; + for (var i = start, j = end - dim; i < end; i += dim) { + sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); + j = i; } - }, - - /* - reoderBuffers: - Reorder attributes based on a new indexBuffer and indexMap. - indexBuffer - Uint16Array of the new ordered indices. - indexMap - Int32Array where the position is the new vertex ID and the value the old vertex ID for each vertex. - vertexCount - Amount of total vertices considered in this reordering (in case you want to grow the vertice stack). - */ - reorderBuffers: function(indexBuffer, indexMap, vertexCount) { + return sum; + } - /* Create a copy of all attributes for reordering. */ - var sortedAttributes = {}; - var types = [ Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array ]; - for( var attr in this.attributes ) { - if(attr == 'index') - continue; - var sourceArray = this.attributes[attr].array; - for ( var i = 0, il = types.length; i < il; i++ ) { - var type = types[i]; - if (sourceArray instanceof type) { - sortedAttributes[attr] = new type( this.attributes[attr].itemSize * vertexCount ); - break; - } - } - } + var ShapeUtils = { + // calculate area of the contour polygon + area: function area(contour) { + var n = contour.length; + var a = 0.0; - /* Move attribute positions based on the new index map */ - for(var new_vid = 0; new_vid < vertexCount; new_vid++) { - var vid = indexMap[new_vid]; - for ( var attr in this.attributes ) { - if(attr == 'index') - continue; - var attrArray = this.attributes[attr].array; - var attrSize = this.attributes[attr].itemSize; - var sortedAttr = sortedAttributes[attr]; - for(var k = 0; k < attrSize; k++) - sortedAttr[ new_vid * attrSize + k ] = attrArray[ vid * attrSize + k ]; + for (var p = n - 1, q = 0; q < n; p = q++) { + a += contour[p].x * contour[q].y - contour[q].x * contour[p].y; } - } - - /* Carry the new sorted buffers locally */ - this.attributes['index'].array = indexBuffer; - for ( var attr in this.attributes ) { - if(attr == 'index') - continue; - this.attributes[attr].array = sortedAttributes[attr]; - this.attributes[attr].numItems = this.attributes[attr].itemSize * vertexCount; - } - }, - - clone: function () { - - var geometry = new THREE.BufferGeometry(); - var types = [ Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array ]; - - for ( var attr in this.attributes ) { - - var sourceAttr = this.attributes[ attr ]; - var sourceArray = sourceAttr.array; - - var attribute = { + return a * 0.5; + }, + isClockWise: function isClockWise(pts) { + return ShapeUtils.area(pts) < 0; + }, + triangulateShape: function triangulateShape(contour, holes) { + var vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ] - itemSize: sourceAttr.itemSize, - array: null + var holeIndices = []; // array of hole indices - }; + var faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ] - for ( var i = 0, il = types.length; i < il; i ++ ) { + removeDupEndPts(contour); + addContour(vertices, contour); // - var type = types[ i ]; + var holeIndex = contour.length; + holes.forEach(removeDupEndPts); - if ( sourceArray instanceof type ) { + for (var i = 0; i < holes.length; i++) { + holeIndices.push(holeIndex); + holeIndex += holes[i].length; + addContour(vertices, holes[i]); + } // - attribute.array = new type( sourceArray ); - break; - } + var triangles = Earcut.triangulate(vertices, holeIndices); // + for (var _i = 0; _i < triangles.length; _i += 3) { + faces.push(triangles.slice(_i, _i + 3)); } - geometry.attributes[ attr ] = attribute; + return faces; + } + }; + function removeDupEndPts(points) { + var l = points.length; + + if (l > 2 && points[l - 1].equals(points[0])) { + points.pop(); } + } - for ( var i = 0, il = this.offsets.length; i < il; i ++ ) { + function addContour(vertices, contour) { + for (var i = 0; i < contour.length; i++) { + vertices.push(contour[i].x); + vertices.push(contour[i].y); + } + } - var offset = this.offsets[ i ]; + var ExtrudeBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(ExtrudeBufferGeometry, _BufferGeometry); - geometry.offsets.push( { + function ExtrudeBufferGeometry(shapes, options) { + var _this; - start: offset.start, - index: offset.index, - count: offset.count + _this = _BufferGeometry.call(this) || this; + _this.type = 'ExtrudeBufferGeometry'; + _this.parameters = { + shapes: shapes, + options: options + }; + shapes = Array.isArray(shapes) ? shapes : [shapes]; - } ); + var scope = _assertThisInitialized(_this); - } + var verticesArray = []; + var uvArray = []; - return geometry; + for (var i = 0, l = shapes.length; i < l; i++) { + var shape = shapes[i]; + addShape(shape); + } // build geometry - }, - dispose: function () { + _this.setAttribute('position', new Float32BufferAttribute(verticesArray, 3)); - this.dispatchEvent( { type: 'dispose' } ); + _this.setAttribute('uv', new Float32BufferAttribute(uvArray, 2)); - } + _this.computeVertexNormals(); // functions -}; -THREE.EventDispatcher.prototype.apply( THREE.BufferGeometry.prototype ); + function addShape(shape) { + var placeholder = []; // options -/** - * @author mrdoob / http://mrdoob.com/ - * @author kile / http://kile.stravaganza.org/ - * @author alteredq / http://alteredqualia.com/ - * @author mikael emtinger / http://gomo.se/ - * @author zz85 / http://www.lab4games.net/zz85/blog - * @author bhouston / http://exocortex.com - */ + var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; + var steps = options.steps !== undefined ? options.steps : 1; + var depth = options.depth !== undefined ? options.depth : 100; + var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; + var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; + var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; + var bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0; + var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3; + var extrudePath = options.extrudePath; + var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; // deprecated options -THREE.Geometry = function () { + if (options.amount !== undefined) { + console.warn('THREE.ExtrudeBufferGeometry: amount has been renamed to depth.'); + depth = options.amount; + } // - this.id = THREE.GeometryIdCount ++; - this.uuid = THREE.Math.generateUUID(); - this.name = ''; + var extrudePts, + extrudeByPath = false; + var splineTube, binormal, normal, position2; - this.vertices = []; - this.colors = []; // one-to-one vertex colors, used in ParticleSystem and Line + if (extrudePath) { + extrudePts = extrudePath.getSpacedPoints(steps); + extrudeByPath = true; + bevelEnabled = false; // bevels not supported for path extrusion + // SETUP TNB variables + // TODO1 - have a .isClosed in spline? - this.faces = []; + splineTube = extrudePath.computeFrenetFrames(steps, false); // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); - this.faceVertexUvs = [[]]; + binormal = new Vector3(); + normal = new Vector3(); + position2 = new Vector3(); + } // Safeguards if bevels are not enabled - this.morphTargets = []; - this.morphColors = []; - this.morphNormals = []; - this.skinWeights = []; - this.skinIndices = []; + if (!bevelEnabled) { + bevelSegments = 0; + bevelThickness = 0; + bevelSize = 0; + bevelOffset = 0; + } // Variables initialization - this.lineDistances = []; - this.boundingBox = null; - this.boundingSphere = null; + var shapePoints = shape.extractPoints(curveSegments); + var vertices = shapePoints.shape; + var holes = shapePoints.holes; + var reverse = !ShapeUtils.isClockWise(vertices); - this.hasTangents = false; + if (reverse) { + vertices = vertices.reverse(); // Maybe we should also check if holes are in the opposite direction, just to be safe ... - this.dynamic = true; // the intermediate typed arrays will be deleted when set to false + for (var h = 0, hl = holes.length; h < hl; h++) { + var ahole = holes[h]; - // update flags + if (ShapeUtils.isClockWise(ahole)) { + holes[h] = ahole.reverse(); + } + } + } - this.verticesNeedUpdate = false; - this.elementsNeedUpdate = false; - this.uvsNeedUpdate = false; - this.normalsNeedUpdate = false; - this.tangentsNeedUpdate = false; - this.colorsNeedUpdate = false; - this.lineDistancesNeedUpdate = false; + var faces = ShapeUtils.triangulateShape(vertices, holes); + /* Vertices */ - this.buffersNeedUpdate = false; + var contour = vertices; // vertices has all points but contour has only points of circumference -}; + for (var _h = 0, _hl = holes.length; _h < _hl; _h++) { + var _ahole = holes[_h]; + vertices = vertices.concat(_ahole); + } -THREE.Geometry.prototype = { + function scalePt2(pt, vec, size) { + if (!vec) console.error("THREE.ExtrudeGeometry: vec does not exist"); + return vec.clone().multiplyScalar(size).add(pt); + } - constructor: THREE.Geometry, + var vlen = vertices.length, + flen = faces.length; // Find directions for point movement - applyMatrix: function ( matrix ) { + function getBevelVec(inPt, inPrev, inNext) { + // computes for inPt the corresponding point inPt' on a new contour + // shifted by 1 unit (length of normalized vector) to the left + // if we walk along contour clockwise, this new contour is outside the old one + // + // inPt' is the intersection of the two lines parallel to the two + // adjacent edges of inPt at a distance of 1 unit on the left side. + var v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt + // good reading for geometry algorithms (here: line-line intersection) + // http://geomalgorithms.com/a05-_intersect-1.html - var normalMatrix = new THREE.Matrix3().getNormalMatrix( matrix ); + var v_prev_x = inPt.x - inPrev.x, + v_prev_y = inPt.y - inPrev.y; + var v_next_x = inNext.x - inPt.x, + v_next_y = inNext.y - inPt.y; + var v_prev_lensq = v_prev_x * v_prev_x + v_prev_y * v_prev_y; // check for collinear edges - for ( var i = 0, il = this.vertices.length; i < il; i ++ ) { + var collinear0 = v_prev_x * v_next_y - v_prev_y * v_next_x; - var vertex = this.vertices[ i ]; - vertex.applyMatrix4( matrix ); + if (Math.abs(collinear0) > Number.EPSILON) { + // not collinear + // length of vectors for normalizing + var v_prev_len = Math.sqrt(v_prev_lensq); + var v_next_len = Math.sqrt(v_next_x * v_next_x + v_next_y * v_next_y); // shift adjacent points by unit vectors to the left - } + var ptPrevShift_x = inPrev.x - v_prev_y / v_prev_len; + var ptPrevShift_y = inPrev.y + v_prev_x / v_prev_len; + var ptNextShift_x = inNext.x - v_next_y / v_next_len; + var ptNextShift_y = inNext.y + v_next_x / v_next_len; // scaling factor for v_prev to intersection point - for ( var i = 0, il = this.faces.length; i < il; i ++ ) { + var sf = ((ptNextShift_x - ptPrevShift_x) * v_next_y - (ptNextShift_y - ptPrevShift_y) * v_next_x) / (v_prev_x * v_next_y - v_prev_y * v_next_x); // vector from inPt to intersection point - var face = this.faces[ i ]; - face.normal.applyMatrix3( normalMatrix ).normalize(); + v_trans_x = ptPrevShift_x + v_prev_x * sf - inPt.x; + v_trans_y = ptPrevShift_y + v_prev_y * sf - inPt.y; // Don't normalize!, otherwise sharp corners become ugly + // but prevent crazy spikes - for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { + var v_trans_lensq = v_trans_x * v_trans_x + v_trans_y * v_trans_y; - face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize(); + if (v_trans_lensq <= 2) { + return new Vector2(v_trans_x, v_trans_y); + } else { + shrink_by = Math.sqrt(v_trans_lensq / 2); + } + } else { + // handle special case of collinear edges + var direction_eq = false; // assumes: opposite - } + if (v_prev_x > Number.EPSILON) { + if (v_next_x > Number.EPSILON) { + direction_eq = true; + } + } else { + if (v_prev_x < -Number.EPSILON) { + if (v_next_x < -Number.EPSILON) { + direction_eq = true; + } + } else { + if (Math.sign(v_prev_y) === Math.sign(v_next_y)) { + direction_eq = true; + } + } + } - } + if (direction_eq) { + // console.log("Warning: lines are a straight sequence"); + v_trans_x = -v_prev_y; + v_trans_y = v_prev_x; + shrink_by = Math.sqrt(v_prev_lensq); + } else { + // console.log("Warning: lines are a straight spike"); + v_trans_x = v_prev_x; + v_trans_y = v_prev_y; + shrink_by = Math.sqrt(v_prev_lensq / 2); + } + } - if ( this.boundingBox instanceof THREE.Box3 ) { + return new Vector2(v_trans_x / shrink_by, v_trans_y / shrink_by); + } - this.computeBoundingBox(); + var contourMovements = []; - } + for (var _i = 0, il = contour.length, j = il - 1, k = _i + 1; _i < il; _i++, j++, k++) { + if (j === il) j = 0; + if (k === il) k = 0; // (j)---(i)---(k) + // console.log('i,j,k', i, j , k) - if ( this.boundingSphere instanceof THREE.Sphere ) { + contourMovements[_i] = getBevelVec(contour[_i], contour[j], contour[k]); + } - this.computeBoundingSphere(); + var holesMovements = []; + var oneHoleMovements, + verticesMovements = contourMovements.concat(); - } + for (var _h2 = 0, _hl2 = holes.length; _h2 < _hl2; _h2++) { + var _ahole2 = holes[_h2]; + oneHoleMovements = []; - }, + for (var _i2 = 0, _il = _ahole2.length, _j = _il - 1, _k = _i2 + 1; _i2 < _il; _i2++, _j++, _k++) { + if (_j === _il) _j = 0; + if (_k === _il) _k = 0; // (j)---(i)---(k) - computeFaceNormals: function () { + oneHoleMovements[_i2] = getBevelVec(_ahole2[_i2], _ahole2[_j], _ahole2[_k]); + } - var cb = new THREE.Vector3(), ab = new THREE.Vector3(); + holesMovements.push(oneHoleMovements); + verticesMovements = verticesMovements.concat(oneHoleMovements); + } // Loop bevelSegments, 1 for the front, 1 for the back - for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) { - var face = this.faces[ f ]; + for (var b = 0; b < bevelSegments; b++) { + //for ( b = bevelSegments; b > 0; b -- ) { + var t = b / bevelSegments; + var z = bevelThickness * Math.cos(t * Math.PI / 2); - var vA = this.vertices[ face.a ]; - var vB = this.vertices[ face.b ]; - var vC = this.vertices[ face.c ]; + var _bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; // contract shape - cb.subVectors( vC, vB ); - ab.subVectors( vA, vB ); - cb.cross( ab ); - cb.normalize(); + for (var _i3 = 0, _il2 = contour.length; _i3 < _il2; _i3++) { + var vert = scalePt2(contour[_i3], contourMovements[_i3], _bs); + v(vert.x, vert.y, -z); + } // expand holes - face.normal.copy( cb ); - } + for (var _h3 = 0, _hl3 = holes.length; _h3 < _hl3; _h3++) { + var _ahole3 = holes[_h3]; + oneHoleMovements = holesMovements[_h3]; - }, + for (var _i4 = 0, _il3 = _ahole3.length; _i4 < _il3; _i4++) { + var _vert = scalePt2(_ahole3[_i4], oneHoleMovements[_i4], _bs); - computeVertexNormals: function ( areaWeighted ) { + v(_vert.x, _vert.y, -z); + } + } + } - var v, vl, f, fl, face, vertices; + var bs = bevelSize + bevelOffset; // Back facing vertices - vertices = new Array( this.vertices.length ); + for (var _i5 = 0; _i5 < vlen; _i5++) { + var _vert2 = bevelEnabled ? scalePt2(vertices[_i5], verticesMovements[_i5], bs) : vertices[_i5]; - for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { + if (!extrudeByPath) { + v(_vert2.x, _vert2.y, 0); + } else { + // v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x ); + normal.copy(splineTube.normals[0]).multiplyScalar(_vert2.x); + binormal.copy(splineTube.binormals[0]).multiplyScalar(_vert2.y); + position2.copy(extrudePts[0]).add(normal).add(binormal); + v(position2.x, position2.y, position2.z); + } + } // Add stepped vertices... + // Including front facing vertices - vertices[ v ] = new THREE.Vector3(); - } + for (var s = 1; s <= steps; s++) { + for (var _i6 = 0; _i6 < vlen; _i6++) { + var _vert3 = bevelEnabled ? scalePt2(vertices[_i6], verticesMovements[_i6], bs) : vertices[_i6]; - if ( areaWeighted ) { + if (!extrudeByPath) { + v(_vert3.x, _vert3.y, depth / steps * s); + } else { + // v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x ); + normal.copy(splineTube.normals[s]).multiplyScalar(_vert3.x); + binormal.copy(splineTube.binormals[s]).multiplyScalar(_vert3.y); + position2.copy(extrudePts[s]).add(normal).add(binormal); + v(position2.x, position2.y, position2.z); + } + } + } // Add bevel segments planes + //for ( b = 1; b <= bevelSegments; b ++ ) { - // vertex normals weighted by triangle areas - // http://www.iquilezles.org/www/articles/normals/normals.htm - var vA, vB, vC, vD; - var cb = new THREE.Vector3(), ab = new THREE.Vector3(), - db = new THREE.Vector3(), dc = new THREE.Vector3(), bc = new THREE.Vector3(); + for (var _b = bevelSegments - 1; _b >= 0; _b--) { + var _t = _b / bevelSegments; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + var _z = bevelThickness * Math.cos(_t * Math.PI / 2); - face = this.faces[ f ]; + var _bs2 = bevelSize * Math.sin(_t * Math.PI / 2) + bevelOffset; // contract shape - vA = this.vertices[ face.a ]; - vB = this.vertices[ face.b ]; - vC = this.vertices[ face.c ]; - cb.subVectors( vC, vB ); - ab.subVectors( vA, vB ); - cb.cross( ab ); + for (var _i7 = 0, _il4 = contour.length; _i7 < _il4; _i7++) { + var _vert4 = scalePt2(contour[_i7], contourMovements[_i7], _bs2); - vertices[ face.a ].add( cb ); - vertices[ face.b ].add( cb ); - vertices[ face.c ].add( cb ); + v(_vert4.x, _vert4.y, depth + _z); + } // expand holes - } - } else { + for (var _h4 = 0, _hl4 = holes.length; _h4 < _hl4; _h4++) { + var _ahole4 = holes[_h4]; + oneHoleMovements = holesMovements[_h4]; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for (var _i8 = 0, _il5 = _ahole4.length; _i8 < _il5; _i8++) { + var _vert5 = scalePt2(_ahole4[_i8], oneHoleMovements[_i8], _bs2); - face = this.faces[ f ]; + if (!extrudeByPath) { + v(_vert5.x, _vert5.y, depth + _z); + } else { + v(_vert5.x, _vert5.y + extrudePts[steps - 1].y, extrudePts[steps - 1].x + _z); + } + } + } + } + /* Faces */ + // Top and bottom faces - vertices[ face.a ].add( face.normal ); - vertices[ face.b ].add( face.normal ); - vertices[ face.c ].add( face.normal ); - } + buildLidFaces(); // Sides faces - } + buildSideFaces(); ///// Internal functions - for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { + function buildLidFaces() { + var start = verticesArray.length / 3; - vertices[ v ].normalize(); + if (bevelEnabled) { + var layer = 0; // steps + 1 - } + var offset = vlen * layer; // Bottom faces - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for (var _i9 = 0; _i9 < flen; _i9++) { + var face = faces[_i9]; + f3(face[2] + offset, face[1] + offset, face[0] + offset); + } - face = this.faces[ f ]; + layer = steps + bevelSegments * 2; + offset = vlen * layer; // Top faces - face.vertexNormals[ 0 ] = vertices[ face.a ].clone(); - face.vertexNormals[ 1 ] = vertices[ face.b ].clone(); - face.vertexNormals[ 2 ] = vertices[ face.c ].clone(); + for (var _i10 = 0; _i10 < flen; _i10++) { + var _face = faces[_i10]; + f3(_face[0] + offset, _face[1] + offset, _face[2] + offset); + } + } else { + // Bottom faces + for (var _i11 = 0; _i11 < flen; _i11++) { + var _face2 = faces[_i11]; + f3(_face2[2], _face2[1], _face2[0]); + } // Top faces - } - }, + for (var _i12 = 0; _i12 < flen; _i12++) { + var _face3 = faces[_i12]; + f3(_face3[0] + vlen * steps, _face3[1] + vlen * steps, _face3[2] + vlen * steps); + } + } - computeMorphNormals: function () { + scope.addGroup(start, verticesArray.length / 3 - start, 0); + } // Create faces for the z-sides of the shape - var i, il, f, fl, face; - // save original normals - // - create temp variables on first access - // otherwise just copy (for faster repeated calls) + function buildSideFaces() { + var start = verticesArray.length / 3; + var layeroffset = 0; + sidewalls(contour, layeroffset); + layeroffset += contour.length; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for (var _h5 = 0, _hl5 = holes.length; _h5 < _hl5; _h5++) { + var _ahole5 = holes[_h5]; + sidewalls(_ahole5, layeroffset); //, true - face = this.faces[ f ]; + layeroffset += _ahole5.length; + } - if ( ! face.__originalFaceNormal ) { + scope.addGroup(start, verticesArray.length / 3 - start, 1); + } - face.__originalFaceNormal = face.normal.clone(); + function sidewalls(contour, layeroffset) { + var i = contour.length; - } else { + while (--i >= 0) { + var _j2 = i; - face.__originalFaceNormal.copy( face.normal ); + var _k2 = i - 1; - } + if (_k2 < 0) _k2 = contour.length - 1; //console.log('b', i,j, i-1, k,vertices.length); - if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = []; + for (var _s = 0, sl = steps + bevelSegments * 2; _s < sl; _s++) { + var slen1 = vlen * _s; + var slen2 = vlen * (_s + 1); - for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) { + var a = layeroffset + _j2 + slen1, + _b2 = layeroffset + _k2 + slen1, + c = layeroffset + _k2 + slen2, + d = layeroffset + _j2 + slen2; - if ( ! face.__originalVertexNormals[ i ] ) { + f4(a, _b2, c, d); + } + } + } - face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone(); + function v(x, y, z) { + placeholder.push(x); + placeholder.push(y); + placeholder.push(z); + } - } else { + function f3(a, b, c) { + addVertex(a); + addVertex(b); + addVertex(c); + var nextIndex = verticesArray.length / 3; + var uvs = uvgen.generateTopUV(scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1); + addUV(uvs[0]); + addUV(uvs[1]); + addUV(uvs[2]); + } - face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] ); + function f4(a, b, c, d) { + addVertex(a); + addVertex(b); + addVertex(d); + addVertex(b); + addVertex(c); + addVertex(d); + var nextIndex = verticesArray.length / 3; + var uvs = uvgen.generateSideWallUV(scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1); + addUV(uvs[0]); + addUV(uvs[1]); + addUV(uvs[3]); + addUV(uvs[1]); + addUV(uvs[2]); + addUV(uvs[3]); + } + function addVertex(index) { + verticesArray.push(placeholder[index * 3 + 0]); + verticesArray.push(placeholder[index * 3 + 1]); + verticesArray.push(placeholder[index * 3 + 2]); } + function addUV(vector2) { + uvArray.push(vector2.x); + uvArray.push(vector2.y); + } } + return _this; } - // use temp geometry to compute face and vertex normals for each morph + var _proto = ExtrudeBufferGeometry.prototype; - var tmpGeo = new THREE.Geometry(); - tmpGeo.faces = this.faces; + _proto.toJSON = function toJSON() { + var data = BufferGeometry.prototype.toJSON.call(this); + var shapes = this.parameters.shapes; + var options = this.parameters.options; + return _toJSON(shapes, options, data); + }; - for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) { + return ExtrudeBufferGeometry; + }(BufferGeometry); + + var WorldUVGenerator = { + generateTopUV: function generateTopUV(geometry, vertices, indexA, indexB, indexC) { + var a_x = vertices[indexA * 3]; + var a_y = vertices[indexA * 3 + 1]; + var b_x = vertices[indexB * 3]; + var b_y = vertices[indexB * 3 + 1]; + var c_x = vertices[indexC * 3]; + var c_y = vertices[indexC * 3 + 1]; + return [new Vector2(a_x, a_y), new Vector2(b_x, b_y), new Vector2(c_x, c_y)]; + }, + generateSideWallUV: function generateSideWallUV(geometry, vertices, indexA, indexB, indexC, indexD) { + var a_x = vertices[indexA * 3]; + var a_y = vertices[indexA * 3 + 1]; + var a_z = vertices[indexA * 3 + 2]; + var b_x = vertices[indexB * 3]; + var b_y = vertices[indexB * 3 + 1]; + var b_z = vertices[indexB * 3 + 2]; + var c_x = vertices[indexC * 3]; + var c_y = vertices[indexC * 3 + 1]; + var c_z = vertices[indexC * 3 + 2]; + var d_x = vertices[indexD * 3]; + var d_y = vertices[indexD * 3 + 1]; + var d_z = vertices[indexD * 3 + 2]; + + if (Math.abs(a_y - b_y) < 0.01) { + return [new Vector2(a_x, 1 - a_z), new Vector2(b_x, 1 - b_z), new Vector2(c_x, 1 - c_z), new Vector2(d_x, 1 - d_z)]; + } else { + return [new Vector2(a_y, 1 - a_z), new Vector2(b_y, 1 - b_z), new Vector2(c_y, 1 - c_z), new Vector2(d_y, 1 - d_z)]; + } + } + }; - // create on first access + function _toJSON(shapes, options, data) { + data.shapes = []; - if ( ! this.morphNormals[ i ] ) { + if (Array.isArray(shapes)) { + for (var i = 0, l = shapes.length; i < l; i++) { + var shape = shapes[i]; + data.shapes.push(shape.uuid); + } + } else { + data.shapes.push(shapes.uuid); + } - this.morphNormals[ i ] = {}; - this.morphNormals[ i ].faceNormals = []; - this.morphNormals[ i ].vertexNormals = []; + if (options.extrudePath !== undefined) data.options.extrudePath = options.extrudePath.toJSON(); + return data; + } - var dstNormalsFace = this.morphNormals[ i ].faceNormals; - var dstNormalsVertex = this.morphNormals[ i ].vertexNormals; + var ExtrudeGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(ExtrudeGeometry, _Geometry); - var faceNormal, vertexNormals; + function ExtrudeGeometry(shapes, options) { + var _this; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + _this = _Geometry.call(this) || this; + _this.type = 'ExtrudeGeometry'; + _this.parameters = { + shapes: shapes, + options: options + }; - faceNormal = new THREE.Vector3(); - vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3() }; + _this.fromBufferGeometry(new ExtrudeBufferGeometry(shapes, options)); - dstNormalsFace.push( faceNormal ); - dstNormalsVertex.push( vertexNormals ); + _this.mergeVertices(); - } + return _this; + } - } + var _proto = ExtrudeGeometry.prototype; - var morphNormals = this.morphNormals[ i ]; + _proto.toJSON = function toJSON() { + var data = _Geometry.prototype.toJSON.call(this); - // set vertices to morph target + var shapes = this.parameters.shapes; + var options = this.parameters.options; + return _toJSON$1(shapes, options, data); + }; - tmpGeo.vertices = this.morphTargets[ i ].vertices; + return ExtrudeGeometry; + }(Geometry); - // compute morph normals - - tmpGeo.computeFaceNormals(); - tmpGeo.computeVertexNormals(); - - // store morph normals - - var faceNormal, vertexNormals; - - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - - face = this.faces[ f ]; - - faceNormal = morphNormals.faceNormals[ f ]; - vertexNormals = morphNormals.vertexNormals[ f ]; - - faceNormal.copy( face.normal ); - - vertexNormals.a.copy( face.vertexNormals[ 0 ] ); - vertexNormals.b.copy( face.vertexNormals[ 1 ] ); - vertexNormals.c.copy( face.vertexNormals[ 2 ] ); + function _toJSON$1(shapes, options, data) { + data.shapes = []; + if (Array.isArray(shapes)) { + for (var i = 0, l = shapes.length; i < l; i++) { + var shape = shapes[i]; + data.shapes.push(shape.uuid); } - + } else { + data.shapes.push(shapes.uuid); } - // restore original normals - - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + if (options.extrudePath !== undefined) data.options.extrudePath = options.extrudePath.toJSON(); + return data; + } - face = this.faces[ f ]; + var IcosahedronBufferGeometry = /*#__PURE__*/function (_PolyhedronBufferGeom) { + _inheritsLoose(IcosahedronBufferGeometry, _PolyhedronBufferGeom); - face.normal = face.__originalFaceNormal; - face.vertexNormals = face.__originalVertexNormals; + function IcosahedronBufferGeometry(radius, detail) { + var _this; + var t = (1 + Math.sqrt(5)) / 2; + var vertices = [-1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, 0, -1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, t, 0, -1, t, 0, 1, -t, 0, -1, -t, 0, 1]; + var indices = [0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1]; + _this = _PolyhedronBufferGeom.call(this, vertices, indices, radius, detail) || this; + _this.type = 'IcosahedronBufferGeometry'; + _this.parameters = { + radius: radius, + detail: detail + }; + return _this; } - }, + return IcosahedronBufferGeometry; + }(PolyhedronBufferGeometry); - computeTangents: function () { + var IcosahedronGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(IcosahedronGeometry, _Geometry); - // based on http://www.terathon.com/code/tangent.html - // tangents go to vertices + function IcosahedronGeometry(radius, detail) { + var _this; - var f, fl, v, vl, i, il, vertexIndex, - face, uv, vA, vB, vC, uvA, uvB, uvC, - x1, x2, y1, y2, z1, z2, - s1, s2, t1, t2, r, t, test, - tan1 = [], tan2 = [], - sdir = new THREE.Vector3(), tdir = new THREE.Vector3(), - tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(), - n = new THREE.Vector3(), w; + _this = _Geometry.call(this) || this; + _this.type = 'IcosahedronGeometry'; + _this.parameters = { + radius: radius, + detail: detail + }; - for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { + _this.fromBufferGeometry(new IcosahedronBufferGeometry(radius, detail)); - tan1[ v ] = new THREE.Vector3(); - tan2[ v ] = new THREE.Vector3(); + _this.mergeVertices(); + return _this; } - function handleTriangle( context, a, b, c, ua, ub, uc ) { - - vA = context.vertices[ a ]; - vB = context.vertices[ b ]; - vC = context.vertices[ c ]; + return IcosahedronGeometry; + }(Geometry); - uvA = uv[ ua ]; - uvB = uv[ ub ]; - uvC = uv[ uc ]; + var LatheBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(LatheBufferGeometry, _BufferGeometry); - x1 = vB.x - vA.x; - x2 = vC.x - vA.x; - y1 = vB.y - vA.y; - y2 = vC.y - vA.y; - z1 = vB.z - vA.z; - z2 = vC.z - vA.z; + function LatheBufferGeometry(points, segments, phiStart, phiLength) { + var _this; - s1 = uvB.x - uvA.x; - s2 = uvC.x - uvA.x; - t1 = uvB.y - uvA.y; - t2 = uvC.y - uvA.y; - - r = 1.0 / ( s1 * t2 - s2 * t1 ); - sdir.set( ( t2 * x1 - t1 * x2 ) * r, - ( t2 * y1 - t1 * y2 ) * r, - ( t2 * z1 - t1 * z2 ) * r ); - tdir.set( ( s1 * x2 - s2 * x1 ) * r, - ( s1 * y2 - s2 * y1 ) * r, - ( s1 * z2 - s2 * z1 ) * r ); - - tan1[ a ].add( sdir ); - tan1[ b ].add( sdir ); - tan1[ c ].add( sdir ); - - tan2[ a ].add( tdir ); - tan2[ b ].add( tdir ); - tan2[ c ].add( tdir ); - - } - - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + _this = _BufferGeometry.call(this) || this; + _this.type = 'LatheBufferGeometry'; + _this.parameters = { + points: points, + segments: segments, + phiStart: phiStart, + phiLength: phiLength + }; + segments = Math.floor(segments) || 12; + phiStart = phiStart || 0; + phiLength = phiLength || Math.PI * 2; // clamp phiLength so it's in range of [ 0, 2PI ] + + phiLength = MathUtils.clamp(phiLength, 0, Math.PI * 2); // buffers + + var indices = []; + var vertices = []; + var uvs = []; // helper variables + + var inverseSegments = 1.0 / segments; + var vertex = new Vector3(); + var uv = new Vector2(); // generate vertices and uvs + + for (var i = 0; i <= segments; i++) { + var phi = phiStart + i * inverseSegments * phiLength; + var sin = Math.sin(phi); + var cos = Math.cos(phi); + + for (var j = 0; j <= points.length - 1; j++) { + // vertex + vertex.x = points[j].x * sin; + vertex.y = points[j].y; + vertex.z = points[j].x * cos; + vertices.push(vertex.x, vertex.y, vertex.z); // uv + + uv.x = i / segments; + uv.y = j / (points.length - 1); + uvs.push(uv.x, uv.y); + } + } // indices - face = this.faces[ f ]; - uv = this.faceVertexUvs[ 0 ][ f ]; // use UV layer 0 for tangents - handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 ); + for (var _i = 0; _i < segments; _i++) { + for (var _j = 0; _j < points.length - 1; _j++) { + var base = _j + _i * points.length; + var a = base; + var b = base + points.length; + var c = base + points.length + 1; + var d = base + 1; // faces - } + indices.push(a, b, d); + indices.push(b, c, d); + } + } // build geometry - var faceIndex = [ 'a', 'b', 'c', 'd' ]; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + _this.setIndex(indices); - face = this.faces[ f ]; + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - for ( i = 0; i < Math.min( face.vertexNormals.length, 3 ); i++ ) { + _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // generate normals - n.copy( face.vertexNormals[ i ] ); - vertexIndex = face[ faceIndex[ i ] ]; + _this.computeVertexNormals(); // if the geometry is closed, we need to average the normals along the seam. + // because the corresponding vertices are identical (but still have different UVs). - t = tan1[ vertexIndex ]; - // Gram-Schmidt orthogonalize + if (phiLength === Math.PI * 2) { + var normals = _this.attributes.normal.array; + var n1 = new Vector3(); + var n2 = new Vector3(); + var n = new Vector3(); // this is the buffer offset for the last line of vertices - tmp.copy( t ); - tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize(); + var _base = segments * points.length * 3; - // Calculate handedness + for (var _i2 = 0, _j2 = 0; _i2 < points.length; _i2++, _j2 += 3) { + // select the normal of the vertex in the first line + n1.x = normals[_j2 + 0]; + n1.y = normals[_j2 + 1]; + n1.z = normals[_j2 + 2]; // select the normal of the vertex in the last line - tmp2.crossVectors( face.vertexNormals[ i ], t ); - test = tmp2.dot( tan2[ vertexIndex ] ); - w = (test < 0.0) ? -1.0 : 1.0; + n2.x = normals[_base + _j2 + 0]; + n2.y = normals[_base + _j2 + 1]; + n2.z = normals[_base + _j2 + 2]; // average normals - face.vertexTangents[ i ] = new THREE.Vector4( tmp.x, tmp.y, tmp.z, w ); + n.addVectors(n1, n2).normalize(); // assign the new values to both normals + normals[_j2 + 0] = normals[_base + _j2 + 0] = n.x; + normals[_j2 + 1] = normals[_base + _j2 + 1] = n.y; + normals[_j2 + 2] = normals[_base + _j2 + 2] = n.z; + } } + return _this; } - this.hasTangents = true; - - }, + return LatheBufferGeometry; + }(BufferGeometry); - computeLineDistances: function ( ) { + var LatheGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(LatheGeometry, _Geometry); - var d = 0; - var vertices = this.vertices; + function LatheGeometry(points, segments, phiStart, phiLength) { + var _this; - for ( var i = 0, il = vertices.length; i < il; i ++ ) { - - if ( i > 0 ) { - - d += vertices[ i ].distanceTo( vertices[ i - 1 ] ); + _this = _Geometry.call(this) || this; + _this.type = 'LatheGeometry'; + _this.parameters = { + points: points, + segments: segments, + phiStart: phiStart, + phiLength: phiLength + }; - } + _this.fromBufferGeometry(new LatheBufferGeometry(points, segments, phiStart, phiLength)); - this.lineDistances[ i ] = d; + _this.mergeVertices(); + return _this; } - }, + return LatheGeometry; + }(Geometry); - computeBoundingBox: function () { + var OctahedronBufferGeometry = /*#__PURE__*/function (_PolyhedronBufferGeom) { + _inheritsLoose(OctahedronBufferGeometry, _PolyhedronBufferGeom); - if ( this.boundingBox === null ) { - - this.boundingBox = new THREE.Box3(); + function OctahedronBufferGeometry(radius, detail) { + var _this; + var vertices = [1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1]; + var indices = [0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2]; + _this = _PolyhedronBufferGeom.call(this, vertices, indices, radius, detail) || this; + _this.type = 'OctahedronBufferGeometry'; + _this.parameters = { + radius: radius, + detail: detail + }; + return _this; } - this.boundingBox.setFromPoints( this.vertices ); - - }, - - computeBoundingSphere: function () { - - if ( this.boundingSphere === null ) { - - this.boundingSphere = new THREE.Sphere(); - - } + return OctahedronBufferGeometry; + }(PolyhedronBufferGeometry); - this.boundingSphere.setFromPoints( this.vertices ); + var OctahedronGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(OctahedronGeometry, _Geometry); - }, + function OctahedronGeometry(radius, detail) { + var _this; - merge: function ( geometry, matrix, materialIndexOffset ) { + _this = _Geometry.call(this) || this; + _this.type = 'OctahedronGeometry'; + _this.parameters = { + radius: radius, + detail: detail + }; - if ( geometry instanceof THREE.Geometry === false ) { + _this.fromBufferGeometry(new OctahedronBufferGeometry(radius, detail)); - console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); - return; + _this.mergeVertices(); + return _this; } - var normalMatrix, - vertexOffset = this.vertices.length, - uvPosition = this.faceVertexUvs[ 0 ].length, - vertices1 = this.vertices, - vertices2 = geometry.vertices, - faces1 = this.faces, - faces2 = geometry.faces, - uvs1 = this.faceVertexUvs[ 0 ], - uvs2 = geometry.faceVertexUvs[ 0 ]; - - if ( materialIndexOffset === undefined ) materialIndexOffset = 0; - - if ( matrix !== undefined ) { + return OctahedronGeometry; + }(Geometry); - normalMatrix = new THREE.Matrix3().getNormalMatrix( matrix ); + /** + * Parametric Surfaces Geometry + * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html + */ - } + function ParametricBufferGeometry(func, slices, stacks) { + BufferGeometry.call(this); + this.type = 'ParametricBufferGeometry'; + this.parameters = { + func: func, + slices: slices, + stacks: stacks + }; // buffers + + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; + var EPS = 0.00001; + var normal = new Vector3(); + var p0 = new Vector3(), + p1 = new Vector3(); + var pu = new Vector3(), + pv = new Vector3(); - // vertices + if (func.length < 3) { + console.error('THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.'); + } // generate vertices, normals and uvs - for ( var i = 0, il = vertices2.length; i < il; i ++ ) { - var vertex = vertices2[ i ]; + var sliceCount = slices + 1; - var vertexCopy = vertex.clone(); + for (var i = 0; i <= stacks; i++) { + var v = i / stacks; - if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix ); + for (var j = 0; j <= slices; j++) { + var u = j / slices; // vertex - vertices1.push( vertexCopy ); + func(u, v, p0); + vertices.push(p0.x, p0.y, p0.z); // normal + // approximate tangent vectors via finite differences - } + if (u - EPS >= 0) { + func(u - EPS, v, p1); + pu.subVectors(p0, p1); + } else { + func(u + EPS, v, p1); + pu.subVectors(p1, p0); + } - // faces + if (v - EPS >= 0) { + func(u, v - EPS, p1); + pv.subVectors(p0, p1); + } else { + func(u, v + EPS, p1); + pv.subVectors(p1, p0); + } // cross product of tangent vectors returns surface normal - for ( i = 0, il = faces2.length; i < il; i ++ ) { - var face = faces2[ i ], faceCopy, normal, color, - faceVertexNormals = face.vertexNormals, - faceVertexColors = face.vertexColors; + normal.crossVectors(pu, pv).normalize(); + normals.push(normal.x, normal.y, normal.z); // uv - faceCopy = new THREE.Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset ); - faceCopy.normal.copy( face.normal ); + uvs.push(u, v); + } + } // generate indices - if ( normalMatrix !== undefined ) { - faceCopy.normal.applyMatrix3( normalMatrix ).normalize(); + for (var _i = 0; _i < stacks; _i++) { + for (var _j = 0; _j < slices; _j++) { + var a = _i * sliceCount + _j; + var b = _i * sliceCount + _j + 1; + var c = (_i + 1) * sliceCount + _j + 1; + var d = (_i + 1) * sliceCount + _j; // faces one and two + indices.push(a, b, d); + indices.push(b, c, d); } + } // build geometry - for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) { - - normal = faceVertexNormals[ j ].clone(); - if ( normalMatrix !== undefined ) { - - normal.applyMatrix3( normalMatrix ).normalize(); + this.setIndex(indices); + this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); + this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); + this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); + } - } + ParametricBufferGeometry.prototype = Object.create(BufferGeometry.prototype); + ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry; - faceCopy.vertexNormals.push( normal ); + /** + * Parametric Surfaces Geometry + * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html + */ - } + function ParametricGeometry(func, slices, stacks) { + Geometry.call(this); + this.type = 'ParametricGeometry'; + this.parameters = { + func: func, + slices: slices, + stacks: stacks + }; + this.fromBufferGeometry(new ParametricBufferGeometry(func, slices, stacks)); + this.mergeVertices(); + } - faceCopy.color.copy( face.color ); + ParametricGeometry.prototype = Object.create(Geometry.prototype); + ParametricGeometry.prototype.constructor = ParametricGeometry; - for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) { + var PlaneGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(PlaneGeometry, _Geometry); - color = faceVertexColors[ j ]; - faceCopy.vertexColors.push( color.clone() ); + function PlaneGeometry(width, height, widthSegments, heightSegments) { + var _this; - } + _this = _Geometry.call(this) || this; + _this.type = 'PlaneGeometry'; + _this.parameters = { + width: width, + height: height, + widthSegments: widthSegments, + heightSegments: heightSegments + }; - faceCopy.materialIndex = face.materialIndex + materialIndexOffset; + _this.fromBufferGeometry(new PlaneBufferGeometry(width, height, widthSegments, heightSegments)); - faces1.push( faceCopy ); + _this.mergeVertices(); + return _this; } - // uvs - - for ( i = 0, il = uvs2.length; i < il; i ++ ) { + return PlaneGeometry; + }(Geometry); - var uv = uvs2[ i ], uvCopy = []; - - if ( uv === undefined ) { - - continue; - - } + var PolyhedronGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(PolyhedronGeometry, _Geometry); - for ( var j = 0, jl = uv.length; j < jl; j ++ ) { + function PolyhedronGeometry(vertices, indices, radius, detail) { + var _this; - uvCopy.push( new THREE.Vector2( uv[ j ].x, uv[ j ].y ) ); + _this = _Geometry.call(this) || this; + _this.type = 'PolyhedronGeometry'; + _this.parameters = { + vertices: vertices, + indices: indices, + radius: radius, + detail: detail + }; - } + _this.fromBufferGeometry(new PolyhedronBufferGeometry(vertices, indices, radius, detail)); - uvs1.push( uvCopy ); + _this.mergeVertices(); + return _this; } - }, + return PolyhedronGeometry; + }(Geometry); - /* - * Checks for duplicate vertices with hashmap. - * Duplicated vertices are removed - * and faces' vertices are updated. - */ + var RingBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(RingBufferGeometry, _BufferGeometry); - mergeVertices: function () { + function RingBufferGeometry(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength) { + var _this; - var verticesMap = {}; // Hashmap for looking up vertice by position coordinates (and making sure they are unique) - var unique = [], changes = []; - - var v, key; - var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001 - var precision = Math.pow( 10, precisionPoints ); - var i,il, face; - var indices, k, j, jl, u; + _this = _BufferGeometry.call(this) || this; + _this.type = 'RingBufferGeometry'; + _this.parameters = { + innerRadius: innerRadius, + outerRadius: outerRadius, + thetaSegments: thetaSegments, + phiSegments: phiSegments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + innerRadius = innerRadius || 0.5; + outerRadius = outerRadius || 1; + thetaStart = thetaStart !== undefined ? thetaStart : 0; + thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; + thetaSegments = thetaSegments !== undefined ? Math.max(3, thetaSegments) : 8; + phiSegments = phiSegments !== undefined ? Math.max(1, phiSegments) : 1; // buffers - for ( i = 0, il = this.vertices.length; i < il; i ++ ) { + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; // some helper variables - v = this.vertices[ i ]; - key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision ); + var radius = innerRadius; + var radiusStep = (outerRadius - innerRadius) / phiSegments; + var vertex = new Vector3(); + var uv = new Vector2(); // generate vertices, normals and uvs - if ( verticesMap[ key ] === undefined ) { + for (var j = 0; j <= phiSegments; j++) { + for (var i = 0; i <= thetaSegments; i++) { + // values are generate from the inside of the ring to the outside + var segment = thetaStart + i / thetaSegments * thetaLength; // vertex - verticesMap[ key ] = i; - unique.push( this.vertices[ i ] ); - changes[ i ] = unique.length - 1; + vertex.x = radius * Math.cos(segment); + vertex.y = radius * Math.sin(segment); + vertices.push(vertex.x, vertex.y, vertex.z); // normal - } else { + normals.push(0, 0, 1); // uv - //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]); - changes[ i ] = changes[ verticesMap[ key ] ]; + uv.x = (vertex.x / outerRadius + 1) / 2; + uv.y = (vertex.y / outerRadius + 1) / 2; + uvs.push(uv.x, uv.y); + } // increase the radius for next row of vertices - } - }; + radius += radiusStep; + } // indices - // if faces are completely degenerate after merging vertices, we - // have to remove them from the geometry. - var faceIndicesToRemove = []; + for (var _j = 0; _j < phiSegments; _j++) { + var thetaSegmentLevel = _j * (thetaSegments + 1); - for( i = 0, il = this.faces.length; i < il; i ++ ) { + for (var _i = 0; _i < thetaSegments; _i++) { + var _segment = _i + thetaSegmentLevel; - face = this.faces[ i ]; + var a = _segment; + var b = _segment + thetaSegments + 1; + var c = _segment + thetaSegments + 2; + var d = _segment + 1; // faces - face.a = changes[ face.a ]; - face.b = changes[ face.b ]; - face.c = changes[ face.c ]; + indices.push(a, b, d); + indices.push(b, c, d); + } + } // build geometry - indices = [ face.a, face.b, face.c ]; - var dupIndex = -1; + _this.setIndex(indices); - // if any duplicate vertices are found in a Face3 - // we have to remove the face as nothing can be saved - for ( var n = 0; n < 3; n ++ ) { - if ( indices[ n ] == indices[ ( n + 1 ) % 3 ] ) { + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - dupIndex = n; - faceIndicesToRemove.push( i ); - break; + _this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - } - } + _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); + return _this; } - for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) { - var idx = faceIndicesToRemove[ i ]; + return RingBufferGeometry; + }(BufferGeometry); + + var RingGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(RingGeometry, _Geometry); - this.faces.splice( idx, 1 ); + function RingGeometry(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength) { + var _this; - for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) { + _this = _Geometry.call(this) || this; + _this.type = 'RingGeometry'; + _this.parameters = { + innerRadius: innerRadius, + outerRadius: outerRadius, + thetaSegments: thetaSegments, + phiSegments: phiSegments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - this.faceVertexUvs[ j ].splice( idx, 1 ); + _this.fromBufferGeometry(new RingBufferGeometry(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength)); - } + _this.mergeVertices(); + return _this; } - // Use unique set of vertices + return RingGeometry; + }(Geometry); - var diff = this.vertices.length - unique.length; - this.vertices = unique; - return diff; + var ShapeBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(ShapeBufferGeometry, _BufferGeometry); - }, + function ShapeBufferGeometry(shapes, curveSegments) { + var _this; - // Geometry splitting + _this = _BufferGeometry.call(this) || this; + _this.type = 'ShapeBufferGeometry'; + _this.parameters = { + shapes: shapes, + curveSegments: curveSegments + }; + curveSegments = curveSegments || 12; // buffers - makeGroups: ( function () { + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; // helper variables - var geometryGroupCounter = 0; - - return function ( usesFaceMaterial, maxVerticesInGroup ) { + var groupStart = 0; + var groupCount = 0; // allow single and array values for "shapes" parameter - var f, fl, face, materialIndex, - groupHash, hash_map = {}; + if (Array.isArray(shapes) === false) { + addShape(shapes); + } else { + for (var i = 0; i < shapes.length; i++) { + addShape(shapes[i]); - var numMorphTargets = this.morphTargets.length; - var numMorphNormals = this.morphNormals.length; + _this.addGroup(groupStart, groupCount, i); // enables MultiMaterial support - this.geometryGroups = {}; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + groupStart += groupCount; + groupCount = 0; + } + } // build geometry - face = this.faces[ f ]; - materialIndex = usesFaceMaterial ? face.materialIndex : 0; - if ( ! ( materialIndex in hash_map ) ) { + _this.setIndex(indices); - hash_map[ materialIndex ] = { 'hash': materialIndex, 'counter': 0 }; + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - } + _this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - groupHash = hash_map[ materialIndex ].hash + '_' + hash_map[ materialIndex ].counter; + _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // helper functions - if ( ! ( groupHash in this.geometryGroups ) ) { - this.geometryGroups[ groupHash ] = { 'faces3': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals }; + function addShape(shape) { + var indexOffset = vertices.length / 3; + var points = shape.extractPoints(curveSegments); + var shapeVertices = points.shape; + var shapeHoles = points.holes; // check direction of vertices + if (ShapeUtils.isClockWise(shapeVertices) === false) { + shapeVertices = shapeVertices.reverse(); } - if ( this.geometryGroups[ groupHash ].vertices + 3 > maxVerticesInGroup ) { - - hash_map[ materialIndex ].counter += 1; - groupHash = hash_map[ materialIndex ].hash + '_' + hash_map[ materialIndex ].counter; - - if ( ! ( groupHash in this.geometryGroups ) ) { - - this.geometryGroups[ groupHash ] = { 'faces3': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals }; + for (var _i = 0, l = shapeHoles.length; _i < l; _i++) { + var shapeHole = shapeHoles[_i]; + if (ShapeUtils.isClockWise(shapeHole) === true) { + shapeHoles[_i] = shapeHole.reverse(); } - } - this.geometryGroups[ groupHash ].faces3.push( f ); - this.geometryGroups[ groupHash ].vertices += 3; - - } + var faces = ShapeUtils.triangulateShape(shapeVertices, shapeHoles); // join vertices of inner and outer paths to a single array - this.geometryGroupsList = []; + for (var _i2 = 0, _l = shapeHoles.length; _i2 < _l; _i2++) { + var _shapeHole = shapeHoles[_i2]; + shapeVertices = shapeVertices.concat(_shapeHole); + } // vertices, normals, uvs - for ( var g in this.geometryGroups ) { - this.geometryGroups[ g ].id = geometryGroupCounter ++; + for (var _i3 = 0, _l2 = shapeVertices.length; _i3 < _l2; _i3++) { + var vertex = shapeVertices[_i3]; + vertices.push(vertex.x, vertex.y, 0); + normals.push(0, 0, 1); + uvs.push(vertex.x, vertex.y); // world uvs + } // incides - this.geometryGroupsList.push( this.geometryGroups[ g ] ); + for (var _i4 = 0, _l3 = faces.length; _i4 < _l3; _i4++) { + var face = faces[_i4]; + var a = face[0] + indexOffset; + var b = face[1] + indexOffset; + var c = face[2] + indexOffset; + indices.push(a, b, c); + groupCount += 3; + } } - }; - - } )(), - - clone: function () { - - var geometry = new THREE.Geometry(); - - var vertices = this.vertices; - - for ( var i = 0, il = vertices.length; i < il; i ++ ) { - - geometry.vertices.push( vertices[ i ].clone() ); - - } - - var faces = this.faces; - - for ( var i = 0, il = faces.length; i < il; i ++ ) { - - geometry.faces.push( faces[ i ].clone() ); - + return _this; } - var uvs = this.faceVertexUvs[ 0 ]; - - for ( var i = 0, il = uvs.length; i < il; i ++ ) { + var _proto = ShapeBufferGeometry.prototype; - var uv = uvs[ i ], uvCopy = []; + _proto.toJSON = function toJSON() { + var data = BufferGeometry.prototype.toJSON.call(this); + var shapes = this.parameters.shapes; + return _toJSON$2(shapes, data); + }; - for ( var j = 0, jl = uv.length; j < jl; j ++ ) { + return ShapeBufferGeometry; + }(BufferGeometry); - uvCopy.push( new THREE.Vector2( uv[ j ].x, uv[ j ].y ) ); + function _toJSON$2(shapes, data) { + data.shapes = []; + if (Array.isArray(shapes)) { + for (var i = 0, l = shapes.length; i < l; i++) { + var shape = shapes[i]; + data.shapes.push(shape.uuid); } - - geometry.faceVertexUvs[ 0 ].push( uvCopy ); - + } else { + data.shapes.push(shapes.uuid); } - return geometry; - - }, - - dispose: function () { - - this.dispatchEvent( { type: 'dispose' } ); - + return data; } -}; - -THREE.EventDispatcher.prototype.apply( THREE.Geometry.prototype ); + var ShapeGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(ShapeGeometry, _Geometry); -THREE.GeometryIdCount = 0; + function ShapeGeometry(shapes, curveSegments) { + var _this; -/** - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - * @author WestLangley / http://github.com/WestLangley -*/ + _this = _Geometry.call(this) || this; + _this.type = 'ShapeGeometry'; -THREE.Camera = function () { - - THREE.Object3D.call( this ); - - this.matrixWorldInverse = new THREE.Matrix4(); - this.projectionMatrix = new THREE.Matrix4(); + if (typeof curveSegments === 'object') { + console.warn('THREE.ShapeGeometry: Options parameter has been removed.'); + curveSegments = curveSegments.curveSegments; + } -}; + _this.parameters = { + shapes: shapes, + curveSegments: curveSegments + }; -THREE.Camera.prototype = Object.create( THREE.Object3D.prototype ); + _this.fromBufferGeometry(new ShapeBufferGeometry(shapes, curveSegments)); -THREE.Camera.prototype.lookAt = function () { + _this.mergeVertices(); - // This routine does not support cameras with rotated and/or translated parent(s) + return _this; + } - var m1 = new THREE.Matrix4(); + var _proto = ShapeGeometry.prototype; - return function ( vector ) { + _proto.toJSON = function toJSON() { + var data = Geometry.prototype.toJSON.call(this); + var shapes = this.parameters.shapes; + return _toJSON$3(shapes, data); + }; - m1.lookAt( this.position, vector, this.up ); + return ShapeGeometry; + }(Geometry); - this.quaternion.setFromRotationMatrix( m1 ); + function _toJSON$3(shapes, data) { + data.shapes = []; - }; + if (Array.isArray(shapes)) { + for (var i = 0, l = shapes.length; i < l; i++) { + var shape = shapes[i]; + data.shapes.push(shape.uuid); + } + } else { + data.shapes.push(shapes.uuid); + } -}(); + return data; + } -THREE.Camera.prototype.clone = function (camera) { + var SphereBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(SphereBufferGeometry, _BufferGeometry); - if ( camera === undefined ) camera = new THREE.Camera(); + function SphereBufferGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength) { + var _this; - THREE.Object3D.prototype.clone.call( this, camera ); + _this = _BufferGeometry.call(this) || this; + _this.type = 'SphereBufferGeometry'; + _this.parameters = { + radius: radius, + widthSegments: widthSegments, + heightSegments: heightSegments, + phiStart: phiStart, + phiLength: phiLength, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + radius = radius || 1; + widthSegments = Math.max(3, Math.floor(widthSegments) || 8); + heightSegments = Math.max(2, Math.floor(heightSegments) || 6); + phiStart = phiStart !== undefined ? phiStart : 0; + phiLength = phiLength !== undefined ? phiLength : Math.PI * 2; + thetaStart = thetaStart !== undefined ? thetaStart : 0; + thetaLength = thetaLength !== undefined ? thetaLength : Math.PI; + var thetaEnd = Math.min(thetaStart + thetaLength, Math.PI); + var index = 0; + var grid = []; + var vertex = new Vector3(); + var normal = new Vector3(); // buffers + + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; // generate vertices, normals and uvs + + for (var iy = 0; iy <= heightSegments; iy++) { + var verticesRow = []; + var v = iy / heightSegments; // special case for the poles + + var uOffset = 0; + + if (iy == 0 && thetaStart == 0) { + uOffset = 0.5 / widthSegments; + } else if (iy == heightSegments && thetaEnd == Math.PI) { + uOffset = -0.5 / widthSegments; + } - camera.matrixWorldInverse.copy( this.matrixWorldInverse ); - camera.projectionMatrix.copy( this.projectionMatrix ); + for (var ix = 0; ix <= widthSegments; ix++) { + var u = ix / widthSegments; // vertex - return camera; -}; + vertex.x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); + vertex.y = radius * Math.cos(thetaStart + v * thetaLength); + vertex.z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); + vertices.push(vertex.x, vertex.y, vertex.z); // normal -/** - * @author alteredq / http://alteredqualia.com/ - */ + normal.copy(vertex).normalize(); + normals.push(normal.x, normal.y, normal.z); // uv -THREE.OrthographicCamera = function ( left, right, top, bottom, near, far ) { + uvs.push(u + uOffset, 1 - v); + verticesRow.push(index++); + } - THREE.Camera.call( this ); + grid.push(verticesRow); + } // indices - this.left = left; - this.right = right; - this.top = top; - this.bottom = bottom; - this.near = ( near !== undefined ) ? near : 0.1; - this.far = ( far !== undefined ) ? far : 2000; + for (var _iy = 0; _iy < heightSegments; _iy++) { + for (var _ix = 0; _ix < widthSegments; _ix++) { + var a = grid[_iy][_ix + 1]; + var b = grid[_iy][_ix]; + var c = grid[_iy + 1][_ix]; + var d = grid[_iy + 1][_ix + 1]; + if (_iy !== 0 || thetaStart > 0) indices.push(a, b, d); + if (_iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d); + } + } // build geometry - this.updateProjectionMatrix(); -}; + _this.setIndex(indices); -THREE.OrthographicCamera.prototype = Object.create( THREE.Camera.prototype ); + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); -THREE.OrthographicCamera.prototype.updateProjectionMatrix = function () { + _this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.projectionMatrix.makeOrthographic( this.left, this.right, this.top, this.bottom, this.near, this.far ); + _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); -}; + return _this; + } -THREE.OrthographicCamera.prototype.clone = function () { + return SphereBufferGeometry; + }(BufferGeometry); - var camera = new THREE.OrthographicCamera(); + var SphereGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(SphereGeometry, _Geometry); - THREE.Camera.prototype.clone.call( this, camera ); + function SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength) { + var _this; - camera.left = this.left; - camera.right = this.right; - camera.top = this.top; - camera.bottom = this.bottom; - - camera.near = this.near; - camera.far = this.far; + _this = _Geometry.call(this) || this; + _this.type = 'SphereGeometry'; + _this.parameters = { + radius: radius, + widthSegments: widthSegments, + heightSegments: heightSegments, + phiStart: phiStart, + phiLength: phiLength, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - return camera; -}; + _this.fromBufferGeometry(new SphereBufferGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength)); -/** - * @author mrdoob / http://mrdoob.com/ - * @author greggman / http://games.greggman.com/ - * @author zz85 / http://www.lab4games.net/zz85/blog - */ + _this.mergeVertices(); -THREE.PerspectiveCamera = function ( fov, aspect, near, far ) { + return _this; + } - THREE.Camera.call( this ); + return SphereGeometry; + }(Geometry); - this.fov = fov !== undefined ? fov : 50; - this.aspect = aspect !== undefined ? aspect : 1; - this.near = near !== undefined ? near : 0.1; - this.far = far !== undefined ? far : 2000; + var TetrahedronBufferGeometry = /*#__PURE__*/function (_PolyhedronBufferGeom) { + _inheritsLoose(TetrahedronBufferGeometry, _PolyhedronBufferGeom); - this.updateProjectionMatrix(); + function TetrahedronBufferGeometry(radius, detail) { + var _this; -}; + var vertices = [1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1]; + var indices = [2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1]; + _this = _PolyhedronBufferGeom.call(this, vertices, indices, radius, detail) || this; + _this.type = 'TetrahedronBufferGeometry'; + _this.parameters = { + radius: radius, + detail: detail + }; + return _this; + } -THREE.PerspectiveCamera.prototype = Object.create( THREE.Camera.prototype ); + return TetrahedronBufferGeometry; + }(PolyhedronBufferGeometry); + var TetrahedronGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(TetrahedronGeometry, _Geometry); -/** - * Uses Focal Length (in mm) to estimate and set FOV - * 35mm (fullframe) camera is used if frame size is not specified; - * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html - */ + function TetrahedronGeometry(radius, detail) { + var _this; -THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameHeight ) { + _this = _Geometry.call(this) || this; + _this.type = 'TetrahedronGeometry'; + _this.parameters = { + radius: radius, + detail: detail + }; - if ( frameHeight === undefined ) frameHeight = 24; + _this.fromBufferGeometry(new TetrahedronBufferGeometry(radius, detail)); - this.fov = 2 * THREE.Math.radToDeg( Math.atan( frameHeight / ( focalLength * 2 ) ) ); - this.updateProjectionMatrix(); + _this.mergeVertices(); -} + return _this; + } + return TetrahedronGeometry; + }(Geometry); -/** - * Sets an offset in a larger frustum. This is useful for multi-window or - * multi-monitor/multi-machine setups. - * - * For example, if you have 3x2 monitors and each monitor is 1920x1080 and - * the monitors are in grid like this - * - * +---+---+---+ - * | A | B | C | - * +---+---+---+ - * | D | E | F | - * +---+---+---+ - * - * then for each monitor you would call it like this - * - * var w = 1920; - * var h = 1080; - * var fullWidth = w * 3; - * var fullHeight = h * 2; - * - * --A-- - * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); - * --B-- - * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); - * --C-- - * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); - * --D-- - * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); - * --E-- - * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); - * --F-- - * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); - * - * Note there is no reason monitors have to be the same size or in a grid. - */ + var TextBufferGeometry = /*#__PURE__*/function (_ExtrudeBufferGeometr) { + _inheritsLoose(TextBufferGeometry, _ExtrudeBufferGeometr); -THREE.PerspectiveCamera.prototype.setViewOffset = function ( fullWidth, fullHeight, x, y, width, height ) { - - this.fullWidth = fullWidth; - this.fullHeight = fullHeight; - this.x = x; - this.y = y; - this.width = width; - this.height = height; - - this.updateProjectionMatrix(); - -}; - - -THREE.PerspectiveCamera.prototype.updateProjectionMatrix = function () { - - if ( this.fullWidth ) { - - var aspect = this.fullWidth / this.fullHeight; - var top = Math.tan( THREE.Math.degToRad( this.fov * 0.5 ) ) * this.near; - var bottom = -top; - var left = aspect * bottom; - var right = aspect * top; - var width = Math.abs( right - left ); - var height = Math.abs( top - bottom ); - - this.projectionMatrix.makeFrustum( - left + this.x * width / this.fullWidth, - left + ( this.x + this.width ) * width / this.fullWidth, - top - ( this.y + this.height ) * height / this.fullHeight, - top - this.y * height / this.fullHeight, - this.near, - this.far - ); + function TextBufferGeometry(text, parameters) { + var _this; - } else { + parameters = parameters || {}; + var font = parameters.font; - this.projectionMatrix.makePerspective( this.fov, this.aspect, this.near, this.far ); + if (!(font && font.isFont)) { + console.error('THREE.TextGeometry: font parameter is not an instance of THREE.Font.'); + return new BufferGeometry() || _assertThisInitialized(_this); + } - } + var shapes = font.generateShapes(text, parameters.size); // translate parameters to ExtrudeGeometry API -}; + parameters.depth = parameters.height !== undefined ? parameters.height : 50; // defaults -THREE.PerspectiveCamera.prototype.clone = function () { + if (parameters.bevelThickness === undefined) parameters.bevelThickness = 10; + if (parameters.bevelSize === undefined) parameters.bevelSize = 8; + if (parameters.bevelEnabled === undefined) parameters.bevelEnabled = false; + _this = _ExtrudeBufferGeometr.call(this, shapes, parameters) || this; + _this.type = 'TextBufferGeometry'; + return _this; + } - var camera = new THREE.PerspectiveCamera(); + return TextBufferGeometry; + }(ExtrudeBufferGeometry); - THREE.Camera.prototype.clone.call( this, camera ); + var TextGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(TextGeometry, _Geometry); - camera.fov = this.fov; - camera.aspect = this.aspect; - camera.near = this.near; - camera.far = this.far; + function TextGeometry(text, parameters) { + var _this; - return camera; -}; + _this = _Geometry.call(this) || this; + _this.type = 'TextGeometry'; + _this.parameters = { + text: text, + parameters: parameters + }; -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.Light = function ( color ) { + _this.fromBufferGeometry(new TextBufferGeometry(text, parameters)); - THREE.Object3D.call( this ); + _this.mergeVertices(); - this.color = new THREE.Color( color ); + return _this; + } -}; + return TextGeometry; + }(Geometry); -THREE.Light.prototype = Object.create( THREE.Object3D.prototype ); + var TorusBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(TorusBufferGeometry, _BufferGeometry); -THREE.Light.prototype.clone = function ( light ) { + function TorusBufferGeometry(radius, tube, radialSegments, tubularSegments, arc) { + var _this; - if ( light === undefined ) light = new THREE.Light(); + _this = _BufferGeometry.call(this) || this; + _this.type = 'TorusBufferGeometry'; + _this.parameters = { + radius: radius, + tube: tube, + radialSegments: radialSegments, + tubularSegments: tubularSegments, + arc: arc + }; + radius = radius || 1; + tube = tube || 0.4; + radialSegments = Math.floor(radialSegments) || 8; + tubularSegments = Math.floor(tubularSegments) || 6; + arc = arc || Math.PI * 2; // buffers + + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; // helper variables + + var center = new Vector3(); + var vertex = new Vector3(); + var normal = new Vector3(); // generate vertices, normals and uvs + + for (var j = 0; j <= radialSegments; j++) { + for (var i = 0; i <= tubularSegments; i++) { + var u = i / tubularSegments * arc; + var v = j / radialSegments * Math.PI * 2; // vertex + + vertex.x = (radius + tube * Math.cos(v)) * Math.cos(u); + vertex.y = (radius + tube * Math.cos(v)) * Math.sin(u); + vertex.z = tube * Math.sin(v); + vertices.push(vertex.x, vertex.y, vertex.z); // normal + + center.x = radius * Math.cos(u); + center.y = radius * Math.sin(u); + normal.subVectors(vertex, center).normalize(); + normals.push(normal.x, normal.y, normal.z); // uv + + uvs.push(i / tubularSegments); + uvs.push(j / radialSegments); + } + } // generate indices - THREE.Object3D.prototype.clone.call( this, light ); - light.color.copy( this.color ); + for (var _j = 1; _j <= radialSegments; _j++) { + for (var _i = 1; _i <= tubularSegments; _i++) { + // indices + var a = (tubularSegments + 1) * _j + _i - 1; + var b = (tubularSegments + 1) * (_j - 1) + _i - 1; + var c = (tubularSegments + 1) * (_j - 1) + _i; + var d = (tubularSegments + 1) * _j + _i; // faces - return light; + indices.push(a, b, d); + indices.push(b, c, d); + } + } // build geometry -}; -/** - * @author mrdoob / http://mrdoob.com/ - */ + _this.setIndex(indices); -THREE.AmbientLight = function ( color ) { + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - THREE.Light.call( this, color ); + _this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); -}; + _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); -THREE.AmbientLight.prototype = Object.create( THREE.Light.prototype ); + return _this; + } -THREE.AmbientLight.prototype.clone = function () { + return TorusBufferGeometry; + }(BufferGeometry); - var light = new THREE.AmbientLight(); + var TorusGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(TorusGeometry, _Geometry); - THREE.Light.prototype.clone.call( this, light ); + function TorusGeometry(radius, tube, radialSegments, tubularSegments, arc) { + var _this; - return light; + _this = _Geometry.call(this) || this; + _this.type = 'TorusGeometry'; + _this.parameters = { + radius: radius, + tube: tube, + radialSegments: radialSegments, + tubularSegments: tubularSegments, + arc: arc + }; -}; + _this.fromBufferGeometry(new TorusBufferGeometry(radius, tube, radialSegments, tubularSegments, arc)); -/** - * @author MPanknin / http://www.redplant.de/ - * @author alteredq / http://alteredqualia.com/ - */ + _this.mergeVertices(); -THREE.AreaLight = function ( color, intensity ) { + return _this; + } - THREE.Light.call( this, color ); + return TorusGeometry; + }(Geometry); - this.normal = new THREE.Vector3( 0, -1, 0 ); - this.right = new THREE.Vector3( 1, 0, 0 ); + var TorusKnotBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(TorusKnotBufferGeometry, _BufferGeometry); - this.intensity = ( intensity !== undefined ) ? intensity : 1; + function TorusKnotBufferGeometry(radius, tube, tubularSegments, radialSegments, p, q) { + var _this; - this.width = 1.0; - this.height = 1.0; + _this = _BufferGeometry.call(this) || this; + _this.type = 'TorusKnotBufferGeometry'; + _this.parameters = { + radius: radius, + tube: tube, + tubularSegments: tubularSegments, + radialSegments: radialSegments, + p: p, + q: q + }; + radius = radius || 1; + tube = tube || 0.4; + tubularSegments = Math.floor(tubularSegments) || 64; + radialSegments = Math.floor(radialSegments) || 8; + p = p || 2; + q = q || 3; // buffers + + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; // helper variables + + var vertex = new Vector3(); + var normal = new Vector3(); + var P1 = new Vector3(); + var P2 = new Vector3(); + var B = new Vector3(); + var T = new Vector3(); + var N = new Vector3(); // generate vertices, normals and uvs + + for (var i = 0; i <= tubularSegments; ++i) { + // the radian "u" is used to calculate the position on the torus curve of the current tubular segement + var u = i / tubularSegments * p * Math.PI * 2; // now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead. + // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions + + calculatePositionOnCurve(u, p, q, radius, P1); + calculatePositionOnCurve(u + 0.01, p, q, radius, P2); // calculate orthonormal basis + + T.subVectors(P2, P1); + N.addVectors(P2, P1); + B.crossVectors(T, N); + N.crossVectors(B, T); // normalize B, N. T can be ignored, we don't use it + + B.normalize(); + N.normalize(); + + for (var j = 0; j <= radialSegments; ++j) { + // now calculate the vertices. they are nothing more than an extrusion of the torus curve. + // because we extrude a shape in the xy-plane, there is no need to calculate a z-value. + var v = j / radialSegments * Math.PI * 2; + var cx = -tube * Math.cos(v); + var cy = tube * Math.sin(v); // now calculate the final vertex position. + // first we orient the extrusion with our basis vectos, then we add it to the current position on the curve + + vertex.x = P1.x + (cx * N.x + cy * B.x); + vertex.y = P1.y + (cx * N.y + cy * B.y); + vertex.z = P1.z + (cx * N.z + cy * B.z); + vertices.push(vertex.x, vertex.y, vertex.z); // normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal) + + normal.subVectors(vertex, P1).normalize(); + normals.push(normal.x, normal.y, normal.z); // uv + + uvs.push(i / tubularSegments); + uvs.push(j / radialSegments); + } + } // generate indices - this.constantAttenuation = 1.5; - this.linearAttenuation = 0.5; - this.quadraticAttenuation = 0.1; -}; + for (var _j = 1; _j <= tubularSegments; _j++) { + for (var _i = 1; _i <= radialSegments; _i++) { + // indices + var a = (radialSegments + 1) * (_j - 1) + (_i - 1); + var b = (radialSegments + 1) * _j + (_i - 1); + var c = (radialSegments + 1) * _j + _i; + var d = (radialSegments + 1) * (_j - 1) + _i; // faces -THREE.AreaLight.prototype = Object.create( THREE.Light.prototype ); + indices.push(a, b, d); + indices.push(b, c, d); + } + } // build geometry -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + _this.setIndex(indices); -THREE.DirectionalLight = function ( color, intensity ) { + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - THREE.Light.call( this, color ); + _this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - this.position.set( 0, 1, 0 ); - this.target = new THREE.Object3D(); + _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // this function calculates the current position on the torus curve - this.intensity = ( intensity !== undefined ) ? intensity : 1; - this.castShadow = false; - this.onlyShadow = false; + function calculatePositionOnCurve(u, p, q, radius, position) { + var cu = Math.cos(u); + var su = Math.sin(u); + var quOverP = q / p * u; + var cs = Math.cos(quOverP); + position.x = radius * (2 + cs) * 0.5 * cu; + position.y = radius * (2 + cs) * su * 0.5; + position.z = radius * Math.sin(quOverP) * 0.5; + } - // + return _this; + } - this.shadowCameraNear = 50; - this.shadowCameraFar = 5000; + return TorusKnotBufferGeometry; + }(BufferGeometry); - this.shadowCameraLeft = -500; - this.shadowCameraRight = 500; - this.shadowCameraTop = 500; - this.shadowCameraBottom = -500; + var TorusKnotGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(TorusKnotGeometry, _Geometry); - this.shadowCameraVisible = false; + function TorusKnotGeometry(radius, tube, tubularSegments, radialSegments, p, q, heightScale) { + var _this; - this.shadowBias = 0; - this.shadowDarkness = 0.5; + _this = _Geometry.call(this) || this; + _this.type = 'TorusKnotGeometry'; + _this.parameters = { + radius: radius, + tube: tube, + tubularSegments: tubularSegments, + radialSegments: radialSegments, + p: p, + q: q + }; + if (heightScale !== undefined) console.warn('THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.'); - this.shadowMapWidth = 512; - this.shadowMapHeight = 512; + _this.fromBufferGeometry(new TorusKnotBufferGeometry(radius, tube, tubularSegments, radialSegments, p, q)); - // + _this.mergeVertices(); - this.shadowCascade = false; + return _this; + } - this.shadowCascadeOffset = new THREE.Vector3( 0, 0, -1000 ); - this.shadowCascadeCount = 2; + return TorusKnotGeometry; + }(Geometry); - this.shadowCascadeBias = [ 0, 0, 0 ]; - this.shadowCascadeWidth = [ 512, 512, 512 ]; - this.shadowCascadeHeight = [ 512, 512, 512 ]; + var TubeBufferGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(TubeBufferGeometry, _BufferGeometry); - this.shadowCascadeNearZ = [ -1.000, 0.990, 0.998 ]; - this.shadowCascadeFarZ = [ 0.990, 0.998, 1.000 ]; + function TubeBufferGeometry(path, tubularSegments, radius, radialSegments, closed) { + var _this; - this.shadowCascadeArray = []; + _this = _BufferGeometry.call(this) || this; + _this.type = 'TubeBufferGeometry'; + _this.parameters = { + path: path, + tubularSegments: tubularSegments, + radius: radius, + radialSegments: radialSegments, + closed: closed + }; + tubularSegments = tubularSegments || 64; + radius = radius || 1; + radialSegments = radialSegments || 8; + closed = closed || false; + var frames = path.computeFrenetFrames(tubularSegments, closed); // expose internals - // + _this.tangents = frames.tangents; + _this.normals = frames.normals; + _this.binormals = frames.binormals; // helper variables - this.shadowMap = null; - this.shadowMapSize = null; - this.shadowCamera = null; - this.shadowMatrix = null; + var vertex = new Vector3(); + var normal = new Vector3(); + var uv = new Vector2(); + var P = new Vector3(); // buffer -}; + var vertices = []; + var normals = []; + var uvs = []; + var indices = []; // create buffer data -THREE.DirectionalLight.prototype = Object.create( THREE.Light.prototype ); + generateBufferData(); // build geometry -THREE.DirectionalLight.prototype.clone = function () { + _this.setIndex(indices); - var light = new THREE.DirectionalLight(); + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); - THREE.Light.prototype.clone.call( this, light ); + _this.setAttribute('normal', new Float32BufferAttribute(normals, 3)); - light.target = this.target.clone(); + _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // functions - light.intensity = this.intensity; - light.castShadow = this.castShadow; - light.onlyShadow = this.onlyShadow; + function generateBufferData() { + for (var i = 0; i < tubularSegments; i++) { + generateSegment(i); + } // if the geometry is not closed, generate the last row of vertices and normals + // at the regular position on the given path + // + // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ) - // - light.shadowCameraNear = this.shadowCameraNear; - light.shadowCameraFar = this.shadowCameraFar; + generateSegment(closed === false ? tubularSegments : 0); // uvs are generated in a separate function. + // this makes it easy compute correct values for closed geometries - light.shadowCameraLeft = this.shadowCameraLeft; - light.shadowCameraRight = this.shadowCameraRight; - light.shadowCameraTop = this.shadowCameraTop; - light.shadowCameraBottom = this.shadowCameraBottom; + generateUVs(); // finally create faces - light.shadowCameraVisible = this.shadowCameraVisible; + generateIndices(); + } - light.shadowBias = this.shadowBias; - light.shadowDarkness = this.shadowDarkness; + function generateSegment(i) { + // we use getPointAt to sample evenly distributed points from the given path + P = path.getPointAt(i / tubularSegments, P); // retrieve corresponding normal and binormal - light.shadowMapWidth = this.shadowMapWidth; - light.shadowMapHeight = this.shadowMapHeight; + var N = frames.normals[i]; + var B = frames.binormals[i]; // generate normals and vertices for the current segment - // + for (var j = 0; j <= radialSegments; j++) { + var v = j / radialSegments * Math.PI * 2; + var sin = Math.sin(v); + var cos = -Math.cos(v); // normal - light.shadowCascade = this.shadowCascade; + normal.x = cos * N.x + sin * B.x; + normal.y = cos * N.y + sin * B.y; + normal.z = cos * N.z + sin * B.z; + normal.normalize(); + normals.push(normal.x, normal.y, normal.z); // vertex - light.shadowCascadeOffset.copy( this.shadowCascadeOffset ); - light.shadowCascadeCount = this.shadowCascadeCount; + vertex.x = P.x + radius * normal.x; + vertex.y = P.y + radius * normal.y; + vertex.z = P.z + radius * normal.z; + vertices.push(vertex.x, vertex.y, vertex.z); + } + } - light.shadowCascadeBias = this.shadowCascadeBias.slice( 0 ); - light.shadowCascadeWidth = this.shadowCascadeWidth.slice( 0 ); - light.shadowCascadeHeight = this.shadowCascadeHeight.slice( 0 ); + function generateIndices() { + for (var j = 1; j <= tubularSegments; j++) { + for (var i = 1; i <= radialSegments; i++) { + var a = (radialSegments + 1) * (j - 1) + (i - 1); + var b = (radialSegments + 1) * j + (i - 1); + var c = (radialSegments + 1) * j + i; + var d = (radialSegments + 1) * (j - 1) + i; // faces - light.shadowCascadeNearZ = this.shadowCascadeNearZ.slice( 0 ); - light.shadowCascadeFarZ = this.shadowCascadeFarZ.slice( 0 ); + indices.push(a, b, d); + indices.push(b, c, d); + } + } + } - return light; + function generateUVs() { + for (var i = 0; i <= tubularSegments; i++) { + for (var j = 0; j <= radialSegments; j++) { + uv.x = i / tubularSegments; + uv.y = j / radialSegments; + uvs.push(uv.x, uv.y); + } + } + } -}; + return _this; + } -/** - * @author alteredq / http://alteredqualia.com/ - */ + var _proto = TubeBufferGeometry.prototype; -THREE.HemisphereLight = function ( skyColor, groundColor, intensity ) { + _proto.toJSON = function toJSON() { + var data = BufferGeometry.prototype.toJSON.call(this); + data.path = this.parameters.path.toJSON(); + return data; + }; - THREE.Light.call( this, skyColor ); + return TubeBufferGeometry; + }(BufferGeometry); - this.position.set( 0, 100, 0 ); + var TubeGeometry = /*#__PURE__*/function (_Geometry) { + _inheritsLoose(TubeGeometry, _Geometry); - this.groundColor = new THREE.Color( groundColor ); - this.intensity = ( intensity !== undefined ) ? intensity : 1; + function TubeGeometry(path, tubularSegments, radius, radialSegments, closed, taper) { + var _this; -}; + _this = _Geometry.call(this) || this; + _this.type = 'TubeGeometry'; + _this.parameters = { + path: path, + tubularSegments: tubularSegments, + radius: radius, + radialSegments: radialSegments, + closed: closed + }; + if (taper !== undefined) console.warn('THREE.TubeGeometry: taper has been removed.'); + var bufferGeometry = new TubeBufferGeometry(path, tubularSegments, radius, radialSegments, closed); // expose internals -THREE.HemisphereLight.prototype = Object.create( THREE.Light.prototype ); + _this.tangents = bufferGeometry.tangents; + _this.normals = bufferGeometry.normals; + _this.binormals = bufferGeometry.binormals; // create geometry -THREE.HemisphereLight.prototype.clone = function () { + _this.fromBufferGeometry(bufferGeometry); - var light = new THREE.HemisphereLight(); + _this.mergeVertices(); - THREE.Light.prototype.clone.call( this, light ); + return _this; + } - light.groundColor.copy( this.groundColor ); - light.intensity = this.intensity; + return TubeGeometry; + }(Geometry); - return light; + var WireframeGeometry = /*#__PURE__*/function (_BufferGeometry) { + _inheritsLoose(WireframeGeometry, _BufferGeometry); -}; + function WireframeGeometry(geometry) { + var _this; -/** - * @author mrdoob / http://mrdoob.com/ - */ + _this = _BufferGeometry.call(this) || this; + _this.type = 'WireframeGeometry'; // buffer -THREE.PointLight = function ( color, intensity, distance ) { + var vertices = []; // helper variables - THREE.Light.call( this, color ); + var edge = [0, 0], + edges = {}; + var keys = ['a', 'b', 'c']; // different logic for Geometry and BufferGeometry - this.intensity = ( intensity !== undefined ) ? intensity : 1; - this.distance = ( distance !== undefined ) ? distance : 0; + if (geometry && geometry.isGeometry) { + // create a data structure that contains all edges without duplicates + var faces = geometry.faces; -}; + for (var i = 0, l = faces.length; i < l; i++) { + var face = faces[i]; -THREE.PointLight.prototype = Object.create( THREE.Light.prototype ); + for (var j = 0; j < 3; j++) { + var edge1 = face[keys[j]]; + var edge2 = face[keys[(j + 1) % 3]]; + edge[0] = Math.min(edge1, edge2); // sorting prevents duplicates -THREE.PointLight.prototype.clone = function () { + edge[1] = Math.max(edge1, edge2); + var key = edge[0] + ',' + edge[1]; - var light = new THREE.PointLight(); + if (edges[key] === undefined) { + edges[key] = { + index1: edge[0], + index2: edge[1] + }; + } + } + } // generate vertices - THREE.Light.prototype.clone.call( this, light ); - light.intensity = this.intensity; - light.distance = this.distance; + for (var _key in edges) { + var e = edges[_key]; + var vertex = geometry.vertices[e.index1]; + vertices.push(vertex.x, vertex.y, vertex.z); + vertex = geometry.vertices[e.index2]; + vertices.push(vertex.x, vertex.y, vertex.z); + } + } else if (geometry && geometry.isBufferGeometry) { + var _vertex = new Vector3(); - return light; + if (geometry.index !== null) { + // indexed BufferGeometry + var position = geometry.attributes.position; + var indices = geometry.index; + var groups = geometry.groups; -}; + if (groups.length === 0) { + groups = [{ + start: 0, + count: indices.count, + materialIndex: 0 + }]; + } // create a data structure that contains all eges without duplicates -/** - * @author alteredq / http://alteredqualia.com/ - */ -THREE.SpotLight = function ( color, intensity, distance, angle, exponent ) { + for (var o = 0, ol = groups.length; o < ol; ++o) { + var group = groups[o]; + var start = group.start; + var count = group.count; - THREE.Light.call( this, color ); + for (var _i = start, _l = start + count; _i < _l; _i += 3) { + for (var _j = 0; _j < 3; _j++) { + var _edge = indices.getX(_i + _j); - this.position.set( 0, 1, 0 ); - this.target = new THREE.Object3D(); + var _edge2 = indices.getX(_i + (_j + 1) % 3); - this.intensity = ( intensity !== undefined ) ? intensity : 1; - this.distance = ( distance !== undefined ) ? distance : 0; - this.angle = ( angle !== undefined ) ? angle : Math.PI / 3; - this.exponent = ( exponent !== undefined ) ? exponent : 10; + edge[0] = Math.min(_edge, _edge2); // sorting prevents duplicates - this.castShadow = false; - this.onlyShadow = false; + edge[1] = Math.max(_edge, _edge2); - // + var _key2 = edge[0] + ',' + edge[1]; - this.shadowCameraNear = 50; - this.shadowCameraFar = 5000; - this.shadowCameraFov = 50; + if (edges[_key2] === undefined) { + edges[_key2] = { + index1: edge[0], + index2: edge[1] + }; + } + } + } + } // generate vertices - this.shadowCameraVisible = false; - this.shadowBias = 0; - this.shadowDarkness = 0.5; + for (var _key3 in edges) { + var _e = edges[_key3]; - this.shadowMapWidth = 512; - this.shadowMapHeight = 512; + _vertex.fromBufferAttribute(position, _e.index1); - // + vertices.push(_vertex.x, _vertex.y, _vertex.z); - this.shadowMap = null; - this.shadowMapSize = null; - this.shadowCamera = null; - this.shadowMatrix = null; + _vertex.fromBufferAttribute(position, _e.index2); -}; + vertices.push(_vertex.x, _vertex.y, _vertex.z); + } + } else { + // non-indexed BufferGeometry + var _position = geometry.attributes.position; -THREE.SpotLight.prototype = Object.create( THREE.Light.prototype ); + for (var _i2 = 0, _l2 = _position.count / 3; _i2 < _l2; _i2++) { + for (var _j2 = 0; _j2 < 3; _j2++) { + // three edges per triangle, an edge is represented as (index1, index2) + // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0) + var index1 = 3 * _i2 + _j2; -THREE.SpotLight.prototype.clone = function () { + _vertex.fromBufferAttribute(_position, index1); - var light = new THREE.SpotLight(); + vertices.push(_vertex.x, _vertex.y, _vertex.z); + var index2 = 3 * _i2 + (_j2 + 1) % 3; - THREE.Light.prototype.clone.call( this, light ); + _vertex.fromBufferAttribute(_position, index2); - light.target = this.target.clone(); + vertices.push(_vertex.x, _vertex.y, _vertex.z); + } + } + } + } // build geometry + + + _this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); + + return _this; + } + + return WireframeGeometry; + }(BufferGeometry); + + var Geometries = /*#__PURE__*/Object.freeze({ + __proto__: null, + BoxGeometry: BoxGeometry, + BoxBufferGeometry: BoxBufferGeometry, + CircleGeometry: CircleGeometry, + CircleBufferGeometry: CircleBufferGeometry, + ConeGeometry: ConeGeometry, + ConeBufferGeometry: ConeBufferGeometry, + CylinderGeometry: CylinderGeometry, + CylinderBufferGeometry: CylinderBufferGeometry, + DodecahedronGeometry: DodecahedronGeometry, + DodecahedronBufferGeometry: DodecahedronBufferGeometry, + EdgesGeometry: EdgesGeometry, + ExtrudeGeometry: ExtrudeGeometry, + ExtrudeBufferGeometry: ExtrudeBufferGeometry, + IcosahedronGeometry: IcosahedronGeometry, + IcosahedronBufferGeometry: IcosahedronBufferGeometry, + LatheGeometry: LatheGeometry, + LatheBufferGeometry: LatheBufferGeometry, + OctahedronGeometry: OctahedronGeometry, + OctahedronBufferGeometry: OctahedronBufferGeometry, + ParametricGeometry: ParametricGeometry, + ParametricBufferGeometry: ParametricBufferGeometry, + PlaneGeometry: PlaneGeometry, + PlaneBufferGeometry: PlaneBufferGeometry, + PolyhedronGeometry: PolyhedronGeometry, + PolyhedronBufferGeometry: PolyhedronBufferGeometry, + RingGeometry: RingGeometry, + RingBufferGeometry: RingBufferGeometry, + ShapeGeometry: ShapeGeometry, + ShapeBufferGeometry: ShapeBufferGeometry, + SphereGeometry: SphereGeometry, + SphereBufferGeometry: SphereBufferGeometry, + TetrahedronGeometry: TetrahedronGeometry, + TetrahedronBufferGeometry: TetrahedronBufferGeometry, + TextGeometry: TextGeometry, + TextBufferGeometry: TextBufferGeometry, + TorusGeometry: TorusGeometry, + TorusBufferGeometry: TorusBufferGeometry, + TorusKnotGeometry: TorusKnotGeometry, + TorusKnotBufferGeometry: TorusKnotBufferGeometry, + TubeGeometry: TubeGeometry, + TubeBufferGeometry: TubeBufferGeometry, + WireframeGeometry: WireframeGeometry + }); + + /** + * parameters = { + * color: + * } + */ - light.intensity = this.intensity; - light.distance = this.distance; - light.angle = this.angle; - light.exponent = this.exponent; + function ShadowMaterial(parameters) { + Material.call(this); + this.type = 'ShadowMaterial'; + this.color = new Color(0x000000); + this.transparent = true; + this.setValues(parameters); + } - light.castShadow = this.castShadow; - light.onlyShadow = this.onlyShadow; + ShadowMaterial.prototype = Object.create(Material.prototype); + ShadowMaterial.prototype.constructor = ShadowMaterial; + ShadowMaterial.prototype.isShadowMaterial = true; - // + ShadowMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.color.copy(source.color); + return this; + }; - light.shadowCameraNear = this.shadowCameraNear; - light.shadowCameraFar = this.shadowCameraFar; - light.shadowCameraFov = this.shadowCameraFov; - - light.shadowCameraVisible = this.shadowCameraVisible; - - light.shadowBias = this.shadowBias; - light.shadowDarkness = this.shadowDarkness; - - light.shadowMapWidth = this.shadowMapWidth; - light.shadowMapHeight = this.shadowMapHeight; - - return light; - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.Cache = function () { - - this.files = {}; - -}; - -THREE.Cache.prototype = { - - constructor: THREE.Cache, - - add: function ( key, file ) { - - // console.log( 'THREE.Cache', 'Adding key:', key ); - - this.files[ key ] = file; - - }, - - get: function ( key ) { - - // console.log( 'THREE.Cache', 'Checking key:', key ); - - return this.files[ key ]; - - }, - - remove: function ( key ) { - - delete this.files[ key ]; - - }, - - clear: function () { - - this.files = {} - - } - -}; -/** - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.Loader = function ( showStatus ) { - - this.showStatus = showStatus; - this.statusDomElement = showStatus ? THREE.Loader.prototype.addStatusElement() : null; - - this.imageLoader = new THREE.ImageLoader(); - - this.onLoadStart = function () {}; - this.onLoadProgress = function () {}; - this.onLoadComplete = function () {}; - -}; - -THREE.Loader.prototype = { - - constructor: THREE.Loader, - - crossOrigin: undefined, - - addStatusElement: function () { - - var e = document.createElement( "div" ); - - e.style.position = "absolute"; - e.style.right = "0px"; - e.style.top = "0px"; - e.style.fontSize = "0.8em"; - e.style.textAlign = "left"; - e.style.background = "rgba(0,0,0,0.25)"; - e.style.color = "#fff"; - e.style.width = "120px"; - e.style.padding = "0.5em 0.5em 0.5em 0.5em"; - e.style.zIndex = 1000; - - e.innerHTML = "Loading ..."; - - return e; - - }, - - updateProgress: function ( progress ) { - - var message = "Loaded "; - - if ( progress.total ) { - - message += ( 100 * progress.loaded / progress.total ).toFixed(0) + "%"; - - - } else { - - message += ( progress.loaded / 1024 ).toFixed(2) + " KB"; - - } - - this.statusDomElement.innerHTML = message; - - }, - - extractUrlBase: function ( url ) { - - var parts = url.split( '/' ); - - if ( parts.length === 1 ) return './'; - - parts.pop(); - - return parts.join( '/' ) + '/'; - - }, - - initMaterials: function ( materials, texturePath ) { - - var array = []; - - for ( var i = 0; i < materials.length; ++ i ) { - - array[ i ] = this.createMaterial( materials[ i ], texturePath ); - - } - - return array; - - }, - - needsTangents: function ( materials ) { - - for( var i = 0, il = materials.length; i < il; i ++ ) { - - var m = materials[ i ]; - - if ( m instanceof THREE.ShaderMaterial ) return true; - - } - - return false; - - }, - - createMaterial: function ( m, texturePath ) { - - var scope = this; - - function nearest_pow2( n ) { - - var l = Math.log( n ) / Math.LN2; - return Math.pow( 2, Math.round( l ) ); - - } - - function create_texture( where, name, sourceFile, repeat, offset, wrap, anisotropy ) { - - var isCompressed = /\.dds$/i.test( sourceFile ); - - var fullPath = texturePath + sourceFile; - - if ( isCompressed ) { - - var texture = THREE.ImageUtils.loadCompressedTexture( fullPath ); - - where[ name ] = texture; - - } else { - - var texture = document.createElement( 'canvas' ); - - where[ name ] = new THREE.Texture( texture ); - - } - - where[ name ].sourceFile = sourceFile; - - if( repeat ) { - - where[ name ].repeat.set( repeat[ 0 ], repeat[ 1 ] ); - - if ( repeat[ 0 ] !== 1 ) where[ name ].wrapS = THREE.RepeatWrapping; - if ( repeat[ 1 ] !== 1 ) where[ name ].wrapT = THREE.RepeatWrapping; - - } - - if ( offset ) { - - where[ name ].offset.set( offset[ 0 ], offset[ 1 ] ); - - } - - if ( wrap ) { - - var wrapMap = { - "repeat": THREE.RepeatWrapping, - "mirror": THREE.MirroredRepeatWrapping - } - - if ( wrapMap[ wrap[ 0 ] ] !== undefined ) where[ name ].wrapS = wrapMap[ wrap[ 0 ] ]; - if ( wrapMap[ wrap[ 1 ] ] !== undefined ) where[ name ].wrapT = wrapMap[ wrap[ 1 ] ]; - - } - - if ( anisotropy ) { - - where[ name ].anisotropy = anisotropy; - - } - - if ( ! isCompressed ) { - - var texture = where[ name ]; - - scope.imageLoader.crossOrigin = scope.crossOrigin; - scope.imageLoader.load( fullPath, function ( image ) { - - if ( THREE.Math.isPowerOfTwo( image.width ) === false || - THREE.Math.isPowerOfTwo( image.height ) === false ) { - - var width = nearest_pow2( image.width ); - var height = nearest_pow2( image.height ); - - texture.image.width = width; - texture.image.height = height; - texture.image.getContext( '2d' ).drawImage( image, 0, 0, width, height ); - - } else { - - texture.image = image; - - } - - texture.needsUpdate = true; - - } ); - - } - - } - - function rgb2hex( rgb ) { - - return ( rgb[ 0 ] * 255 << 16 ) + ( rgb[ 1 ] * 255 << 8 ) + rgb[ 2 ] * 255; - - } - - // defaults - - var mtype = "MeshLambertMaterial"; - var mpars = { color: 0xeeeeee, opacity: 1.0, map: null, lightMap: null, normalMap: null, bumpMap: null, wireframe: false }; - - // parameters from model file - - if ( m.shading ) { - - var shading = m.shading.toLowerCase(); - - if ( shading === "phong" ) mtype = "MeshPhongMaterial"; - else if ( shading === "basic" ) mtype = "MeshBasicMaterial"; - - } - - if ( m.blending !== undefined && THREE[ m.blending ] !== undefined ) { - - mpars.blending = THREE[ m.blending ]; - - } - - if ( m.transparent !== undefined || m.opacity < 1.0 ) { - - mpars.transparent = m.transparent; - - } - - if ( m.depthTest !== undefined ) { - - mpars.depthTest = m.depthTest; - - } - - if ( m.depthWrite !== undefined ) { - - mpars.depthWrite = m.depthWrite; - - } - - if ( m.visible !== undefined ) { - - mpars.visible = m.visible; - - } - - if ( m.flipSided !== undefined ) { - - mpars.side = THREE.BackSide; - - } - - if ( m.doubleSided !== undefined ) { - - mpars.side = THREE.DoubleSide; - - } - - if ( m.wireframe !== undefined ) { - - mpars.wireframe = m.wireframe; - - } - - if ( m.vertexColors !== undefined ) { - - if ( m.vertexColors === "face" ) { - - mpars.vertexColors = THREE.FaceColors; - - } else if ( m.vertexColors ) { - - mpars.vertexColors = THREE.VertexColors; - - } - - } - - // colors - - if ( m.colorDiffuse ) { - - mpars.color = rgb2hex( m.colorDiffuse ); - - } else if ( m.DbgColor ) { - - mpars.color = m.DbgColor; - - } - - if ( m.colorSpecular ) { - - mpars.specular = rgb2hex( m.colorSpecular ); - - } - - if ( m.colorAmbient ) { - - mpars.ambient = rgb2hex( m.colorAmbient ); - - } - - if ( m.colorEmissive ) { - - mpars.emissive = rgb2hex( m.colorEmissive ); - - } - - // modifiers - - if ( m.transparency ) { - - mpars.opacity = m.transparency; - - } - - if ( m.specularCoef ) { - - mpars.shininess = m.specularCoef; - - } - - // textures - - if ( m.mapDiffuse && texturePath ) { - - create_texture( mpars, "map", m.mapDiffuse, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy ); - - } - - if ( m.mapLight && texturePath ) { - - create_texture( mpars, "lightMap", m.mapLight, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy ); - - } - - if ( m.mapBump && texturePath ) { - - create_texture( mpars, "bumpMap", m.mapBump, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy ); - - } - - if ( m.mapNormal && texturePath ) { - - create_texture( mpars, "normalMap", m.mapNormal, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy ); - - } - - if ( m.mapSpecular && texturePath ) { - - create_texture( mpars, "specularMap", m.mapSpecular, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy ); - - } - - // - - if ( m.mapBumpScale ) { - - mpars.bumpScale = m.mapBumpScale; - - } - - // special case for normal mapped material - - if ( m.mapNormal ) { - - var shader = THREE.ShaderLib[ "normalmap" ]; - var uniforms = THREE.UniformsUtils.clone( shader.uniforms ); - - uniforms[ "tNormal" ].value = mpars.normalMap; - - if ( m.mapNormalFactor ) { - - uniforms[ "uNormalScale" ].value.set( m.mapNormalFactor, m.mapNormalFactor ); - - } - - if ( mpars.map ) { - - uniforms[ "tDiffuse" ].value = mpars.map; - uniforms[ "enableDiffuse" ].value = true; - - } - - if ( mpars.specularMap ) { - - uniforms[ "tSpecular" ].value = mpars.specularMap; - uniforms[ "enableSpecular" ].value = true; - - } - - if ( mpars.lightMap ) { - - uniforms[ "tAO" ].value = mpars.lightMap; - uniforms[ "enableAO" ].value = true; - - } - - // for the moment don't handle displacement texture - - uniforms[ "diffuse" ].value.setHex( mpars.color ); - uniforms[ "specular" ].value.setHex( mpars.specular ); - uniforms[ "ambient" ].value.setHex( mpars.ambient ); - - uniforms[ "shininess" ].value = mpars.shininess; - - if ( mpars.opacity !== undefined ) { - - uniforms[ "opacity" ].value = mpars.opacity; - - } - - var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true }; - var material = new THREE.ShaderMaterial( parameters ); - - if ( mpars.transparent ) { - - material.transparent = true; - - } - - } else { - - var material = new THREE[ mtype ]( mpars ); - - } - - if ( m.DbgName !== undefined ) material.name = m.DbgName; - - return material; - - } - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.XHRLoader = function ( manager ) { - - this.cache = new THREE.Cache(); - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - -}; - -THREE.XHRLoader.prototype = { - - constructor: THREE.XHRLoader, - - load: function ( url, onLoad, onProgress, onError ) { + function RawShaderMaterial(parameters) { + ShaderMaterial.call(this, parameters); + this.type = 'RawShaderMaterial'; + } - var scope = this; + RawShaderMaterial.prototype = Object.create(ShaderMaterial.prototype); + RawShaderMaterial.prototype.constructor = RawShaderMaterial; + RawShaderMaterial.prototype.isRawShaderMaterial = true; - var cached = scope.cache.get( url ); + /** + * parameters = { + * color: , + * roughness: , + * metalness: , + * opacity: , + * + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalMapType: THREE.TangentSpaceNormalMap, + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * roughnessMap: new THREE.Texture( ), + * + * metalnessMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), + * envMapIntensity: + * + * refractionRatio: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - if ( cached !== undefined ) { + function MeshStandardMaterial(parameters) { + Material.call(this); + this.defines = { + 'STANDARD': '' + }; + this.type = 'MeshStandardMaterial'; + this.color = new Color(0xffffff); // diffuse + + this.roughness = 1.0; + this.metalness = 0.0; + this.map = null; + this.lightMap = null; + this.lightMapIntensity = 1.0; + this.aoMap = null; + this.aoMapIntensity = 1.0; + this.emissive = new Color(0x000000); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + this.bumpMap = null; + this.bumpScale = 1; + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2(1, 1); + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + this.roughnessMap = null; + this.metalnessMap = null; + this.alphaMap = null; + this.envMap = null; + this.envMapIntensity = 1.0; + this.refractionRatio = 0.98; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; + this.vertexTangents = false; + this.setValues(parameters); + } + + MeshStandardMaterial.prototype = Object.create(Material.prototype); + MeshStandardMaterial.prototype.constructor = MeshStandardMaterial; + MeshStandardMaterial.prototype.isMeshStandardMaterial = true; + + MeshStandardMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.defines = { + 'STANDARD': '' + }; + this.color.copy(source.color); + this.roughness = source.roughness; + this.metalness = source.metalness; + this.map = source.map; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + this.emissive.copy(source.emissive); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy(source.normalScale); + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + this.roughnessMap = source.roughnessMap; + this.metalnessMap = source.metalnessMap; + this.alphaMap = source.alphaMap; + this.envMap = source.envMap; + this.envMapIntensity = source.envMapIntensity; + this.refractionRatio = source.refractionRatio; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; + this.vertexTangents = source.vertexTangents; + return this; + }; - onLoad( cached ); - return; + /** + * parameters = { + * clearcoat: , + * clearcoatMap: new THREE.Texture( ), + * clearcoatRoughness: , + * clearcoatRoughnessMap: new THREE.Texture( ), + * clearcoatNormalScale: , + * clearcoatNormalMap: new THREE.Texture( ), + * + * reflectivity: , + * ior: , + * + * sheen: , + * + * transmission: , + * transmissionMap: new THREE.Texture( ) + * } + */ + function MeshPhysicalMaterial(parameters) { + MeshStandardMaterial.call(this); + this.defines = { + 'STANDARD': '', + 'PHYSICAL': '' + }; + this.type = 'MeshPhysicalMaterial'; + this.clearcoat = 0.0; + this.clearcoatMap = null; + this.clearcoatRoughness = 0.0; + this.clearcoatRoughnessMap = null; + this.clearcoatNormalScale = new Vector2(1, 1); + this.clearcoatNormalMap = null; + this.reflectivity = 0.5; // maps to F0 = 0.04 + + Object.defineProperty(this, 'ior', { + get: function get() { + return (1 + 0.4 * this.reflectivity) / (1 - 0.4 * this.reflectivity); + }, + set: function set(ior) { + this.reflectivity = MathUtils.clamp(2.5 * (ior - 1) / (ior + 1), 0, 1); + } + }); + this.sheen = null; // null will disable sheen bsdf + + this.transmission = 0.0; + this.transmissionMap = null; + this.setValues(parameters); + } + + MeshPhysicalMaterial.prototype = Object.create(MeshStandardMaterial.prototype); + MeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial; + MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true; + + MeshPhysicalMaterial.prototype.copy = function (source) { + MeshStandardMaterial.prototype.copy.call(this, source); + this.defines = { + 'STANDARD': '', + 'PHYSICAL': '' + }; + this.clearcoat = source.clearcoat; + this.clearcoatMap = source.clearcoatMap; + this.clearcoatRoughness = source.clearcoatRoughness; + this.clearcoatRoughnessMap = source.clearcoatRoughnessMap; + this.clearcoatNormalMap = source.clearcoatNormalMap; + this.clearcoatNormalScale.copy(source.clearcoatNormalScale); + this.reflectivity = source.reflectivity; + + if (source.sheen) { + this.sheen = (this.sheen || new Color()).copy(source.sheen); + } else { + this.sheen = null; } - var request = new XMLHttpRequest(); - - if ( onLoad !== undefined ) { - - request.addEventListener( 'load', function ( event ) { + this.transmission = source.transmission; + this.transmissionMap = source.transmissionMap; + return this; + }; - scope.cache.add( url, event.target.responseText ); + /** + * parameters = { + * color: , + * specular: , + * shininess: , + * opacity: , + * + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalMapType: THREE.TangentSpaceNormalMap, + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), + * combine: THREE.MultiplyOperation, + * reflectivity: , + * refractionRatio: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - onLoad( event.target.responseText ); - scope.manager.itemEnd( url ); + function MeshPhongMaterial(parameters) { + Material.call(this); + this.type = 'MeshPhongMaterial'; + this.color = new Color(0xffffff); // diffuse + + this.specular = new Color(0x111111); + this.shininess = 30; + this.map = null; + this.lightMap = null; + this.lightMapIntensity = 1.0; + this.aoMap = null; + this.aoMapIntensity = 1.0; + this.emissive = new Color(0x000000); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + this.bumpMap = null; + this.bumpScale = 1; + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2(1, 1); + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + this.specularMap = null; + this.alphaMap = null; + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; + this.setValues(parameters); + } + + MeshPhongMaterial.prototype = Object.create(Material.prototype); + MeshPhongMaterial.prototype.constructor = MeshPhongMaterial; + MeshPhongMaterial.prototype.isMeshPhongMaterial = true; + + MeshPhongMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.color.copy(source.color); + this.specular.copy(source.specular); + this.shininess = source.shininess; + this.map = source.map; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + this.emissive.copy(source.emissive); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy(source.normalScale); + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + this.specularMap = source.specularMap; + this.alphaMap = source.alphaMap; + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; + return this; + }; - }, false ); + /** + * parameters = { + * color: , + * + * map: new THREE.Texture( ), + * gradientMap: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalMapType: THREE.TangentSpaceNormalMap, + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * alphaMap: new THREE.Texture( ), + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - } - - if ( onProgress !== undefined ) { + function MeshToonMaterial(parameters) { + Material.call(this); + this.defines = { + 'TOON': '' + }; + this.type = 'MeshToonMaterial'; + this.color = new Color(0xffffff); + this.map = null; + this.gradientMap = null; + this.lightMap = null; + this.lightMapIntensity = 1.0; + this.aoMap = null; + this.aoMapIntensity = 1.0; + this.emissive = new Color(0x000000); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + this.bumpMap = null; + this.bumpScale = 1; + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2(1, 1); + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + this.alphaMap = null; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; + this.setValues(parameters); + } + + MeshToonMaterial.prototype = Object.create(Material.prototype); + MeshToonMaterial.prototype.constructor = MeshToonMaterial; + MeshToonMaterial.prototype.isMeshToonMaterial = true; + + MeshToonMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.color.copy(source.color); + this.map = source.map; + this.gradientMap = source.gradientMap; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + this.emissive.copy(source.emissive); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy(source.normalScale); + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + this.alphaMap = source.alphaMap; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; + return this; + }; - request.addEventListener( 'progress', function ( event ) { + /** + * parameters = { + * opacity: , + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalMapType: THREE.TangentSpaceNormalMap, + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * wireframe: , + * wireframeLinewidth: + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - onProgress( event ); + function MeshNormalMaterial(parameters) { + Material.call(this); + this.type = 'MeshNormalMaterial'; + this.bumpMap = null; + this.bumpScale = 1; + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2(1, 1); + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.fog = false; + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; + this.setValues(parameters); + } + + MeshNormalMaterial.prototype = Object.create(Material.prototype); + MeshNormalMaterial.prototype.constructor = MeshNormalMaterial; + MeshNormalMaterial.prototype.isMeshNormalMaterial = true; + + MeshNormalMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy(source.normalScale); + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; + return this; + }; - }, false ); + /** + * parameters = { + * color: , + * opacity: , + * + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), + * combine: THREE.Multiply, + * reflectivity: , + * refractionRatio: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - } + function MeshLambertMaterial(parameters) { + Material.call(this); + this.type = 'MeshLambertMaterial'; + this.color = new Color(0xffffff); // diffuse + + this.map = null; + this.lightMap = null; + this.lightMapIntensity = 1.0; + this.aoMap = null; + this.aoMapIntensity = 1.0; + this.emissive = new Color(0x000000); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + this.specularMap = null; + this.alphaMap = null; + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; + this.setValues(parameters); + } + + MeshLambertMaterial.prototype = Object.create(Material.prototype); + MeshLambertMaterial.prototype.constructor = MeshLambertMaterial; + MeshLambertMaterial.prototype.isMeshLambertMaterial = true; + + MeshLambertMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.color.copy(source.color); + this.map = source.map; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + this.emissive.copy(source.emissive); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + this.specularMap = source.specularMap; + this.alphaMap = source.alphaMap; + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; + return this; + }; - if ( onError !== undefined ) { + /** + * parameters = { + * color: , + * opacity: , + * + * matcap: new THREE.Texture( ), + * + * map: new THREE.Texture( ), + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalMapType: THREE.TangentSpaceNormalMap, + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * alphaMap: new THREE.Texture( ), + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - request.addEventListener( 'error', function ( event ) { + function MeshMatcapMaterial(parameters) { + Material.call(this); + this.defines = { + 'MATCAP': '' + }; + this.type = 'MeshMatcapMaterial'; + this.color = new Color(0xffffff); // diffuse + + this.matcap = null; + this.map = null; + this.bumpMap = null; + this.bumpScale = 1; + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2(1, 1); + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + this.alphaMap = null; + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; + this.setValues(parameters); + } + + MeshMatcapMaterial.prototype = Object.create(Material.prototype); + MeshMatcapMaterial.prototype.constructor = MeshMatcapMaterial; + MeshMatcapMaterial.prototype.isMeshMatcapMaterial = true; + + MeshMatcapMaterial.prototype.copy = function (source) { + Material.prototype.copy.call(this, source); + this.defines = { + 'MATCAP': '' + }; + this.color.copy(source.color); + this.matcap = source.matcap; + this.map = source.map; + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy(source.normalScale); + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + this.alphaMap = source.alphaMap; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; + return this; + }; - onError( event ); + /** + * parameters = { + * color: , + * opacity: , + * + * linewidth: , + * + * scale: , + * dashSize: , + * gapSize: + * } + */ - }, false ); + function LineDashedMaterial(parameters) { + LineBasicMaterial.call(this); + this.type = 'LineDashedMaterial'; + this.scale = 1; + this.dashSize = 3; + this.gapSize = 1; + this.setValues(parameters); + } - } + LineDashedMaterial.prototype = Object.create(LineBasicMaterial.prototype); + LineDashedMaterial.prototype.constructor = LineDashedMaterial; + LineDashedMaterial.prototype.isLineDashedMaterial = true; - if ( this.crossOrigin !== undefined ) request.crossOrigin = this.crossOrigin; + LineDashedMaterial.prototype.copy = function (source) { + LineBasicMaterial.prototype.copy.call(this, source); + this.scale = source.scale; + this.dashSize = source.dashSize; + this.gapSize = source.gapSize; + return this; + }; - request.open( 'GET', url, true ); - request.send( null ); + var Materials = /*#__PURE__*/Object.freeze({ + __proto__: null, + ShadowMaterial: ShadowMaterial, + SpriteMaterial: SpriteMaterial, + RawShaderMaterial: RawShaderMaterial, + ShaderMaterial: ShaderMaterial, + PointsMaterial: PointsMaterial, + MeshPhysicalMaterial: MeshPhysicalMaterial, + MeshStandardMaterial: MeshStandardMaterial, + MeshPhongMaterial: MeshPhongMaterial, + MeshToonMaterial: MeshToonMaterial, + MeshNormalMaterial: MeshNormalMaterial, + MeshLambertMaterial: MeshLambertMaterial, + MeshDepthMaterial: MeshDepthMaterial, + MeshDistanceMaterial: MeshDistanceMaterial, + MeshBasicMaterial: MeshBasicMaterial, + MeshMatcapMaterial: MeshMatcapMaterial, + LineDashedMaterial: LineDashedMaterial, + LineBasicMaterial: LineBasicMaterial, + Material: Material + }); + + var AnimationUtils = { + // same as Array.prototype.slice, but also works on typed arrays + arraySlice: function arraySlice(array, from, to) { + if (AnimationUtils.isTypedArray(array)) { + // in ios9 array.subarray(from, undefined) will return empty array + // but array.subarray(from) or array.subarray(from, len) is correct + return new array.constructor(array.subarray(from, to !== undefined ? to : array.length)); + } + + return array.slice(from, to); + }, + // converts an array to a specific type + convertArray: function convertArray(array, type, forceClone) { + if (!array || // let 'undefined' and 'null' pass + !forceClone && array.constructor === type) return array; - scope.manager.itemStart( url ); + if (typeof type.BYTES_PER_ELEMENT === 'number') { + return new type(array); // create typed array + } - }, + return Array.prototype.slice.call(array); // create Array + }, + isTypedArray: function isTypedArray(object) { + return ArrayBuffer.isView(object) && !(object instanceof DataView); + }, + // returns an array by which times and values can be sorted + getKeyframeOrder: function getKeyframeOrder(times) { + function compareTime(i, j) { + return times[i] - times[j]; + } - setCrossOrigin: function ( value ) { + var n = times.length; + var result = new Array(n); - this.crossOrigin = value; + for (var i = 0; i !== n; ++i) { + result[i] = i; + } - } + result.sort(compareTime); + return result; + }, + // uses the array previously returned by 'getKeyframeOrder' to sort data + sortedArray: function sortedArray(values, stride, order) { + var nValues = values.length; + var result = new values.constructor(nValues); -}; + for (var i = 0, dstOffset = 0; dstOffset !== nValues; ++i) { + var srcOffset = order[i] * stride; -/** - * @author mrdoob / http://mrdoob.com/ - */ + for (var j = 0; j !== stride; ++j) { + result[dstOffset++] = values[srcOffset + j]; + } + } -THREE.ImageLoader = function ( manager ) { + return result; + }, + // function for parsing AOS keyframe formats + flattenJSON: function flattenJSON(jsonKeys, times, values, valuePropertyName) { + var i = 1, + key = jsonKeys[0]; - this.cache = new THREE.Cache(); - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + while (key !== undefined && key[valuePropertyName] === undefined) { + key = jsonKeys[i++]; + } -}; + if (key === undefined) return; // no data -THREE.ImageLoader.prototype = { + var value = key[valuePropertyName]; + if (value === undefined) return; // no data - constructor: THREE.ImageLoader, + if (Array.isArray(value)) { + do { + value = key[valuePropertyName]; - load: function ( url, onLoad, onProgress, onError ) { + if (value !== undefined) { + times.push(key.time); + values.push.apply(values, value); // push all elements + } - var scope = this; + key = jsonKeys[i++]; + } while (key !== undefined); + } else if (value.toArray !== undefined) { + // ...assume THREE.Math-ish + do { + value = key[valuePropertyName]; - var cached = scope.cache.get( url ); + if (value !== undefined) { + times.push(key.time); + value.toArray(values, values.length); + } - if ( cached !== undefined ) { + key = jsonKeys[i++]; + } while (key !== undefined); + } else { + // otherwise push as-is + do { + value = key[valuePropertyName]; - onLoad( cached ); - return; + if (value !== undefined) { + times.push(key.time); + values.push(value); + } - } + key = jsonKeys[i++]; + } while (key !== undefined); + } + }, + subclip: function subclip(sourceClip, name, startFrame, endFrame, fps) { + fps = fps || 30; + var clip = sourceClip.clone(); + clip.name = name; + var tracks = []; + + for (var i = 0; i < clip.tracks.length; ++i) { + var track = clip.tracks[i]; + var valueSize = track.getValueSize(); + var times = []; + var values = []; + + for (var j = 0; j < track.times.length; ++j) { + var frame = track.times[j] * fps; + if (frame < startFrame || frame >= endFrame) continue; + times.push(track.times[j]); + + for (var k = 0; k < valueSize; ++k) { + values.push(track.values[j * valueSize + k]); + } + } - var image = document.createElement( 'img' ); + if (times.length === 0) continue; + track.times = AnimationUtils.convertArray(times, track.times.constructor); + track.values = AnimationUtils.convertArray(values, track.values.constructor); + tracks.push(track); + } - if ( onLoad !== undefined ) { + clip.tracks = tracks; // find minimum .times value across all tracks in the trimmed clip - image.addEventListener( 'load', function ( event ) { + var minStartTime = Infinity; - scope.cache.add( url, this ); + for (var _i = 0; _i < clip.tracks.length; ++_i) { + if (minStartTime > clip.tracks[_i].times[0]) { + minStartTime = clip.tracks[_i].times[0]; + } + } // shift all tracks such that clip begins at t=0 - onLoad( this ); - scope.manager.itemEnd( url ); - }, false ); + for (var _i2 = 0; _i2 < clip.tracks.length; ++_i2) { + clip.tracks[_i2].shift(-1 * minStartTime); + } - } + clip.resetDuration(); + return clip; + }, + makeClipAdditive: function makeClipAdditive(targetClip, referenceFrame, referenceClip, fps) { + if (referenceFrame === undefined) referenceFrame = 0; + if (referenceClip === undefined) referenceClip = targetClip; + if (fps === undefined || fps <= 0) fps = 30; + var numTracks = referenceClip.tracks.length; + var referenceTime = referenceFrame / fps; // Make each track's values relative to the values at the reference frame + + var _loop = function _loop(i) { + var referenceTrack = referenceClip.tracks[i]; + var referenceTrackType = referenceTrack.ValueTypeName; // Skip this track if it's non-numeric + + if (referenceTrackType === 'bool' || referenceTrackType === 'string') return "continue"; // Find the track in the target clip whose name and type matches the reference track + + var targetTrack = targetClip.tracks.find(function (track) { + return track.name === referenceTrack.name && track.ValueTypeName === referenceTrackType; + }); + if (targetTrack === undefined) return "continue"; + var referenceOffset = 0; + var referenceValueSize = referenceTrack.getValueSize(); + + if (referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { + referenceOffset = referenceValueSize / 3; + } - if ( onProgress !== undefined ) { + var targetOffset = 0; + var targetValueSize = targetTrack.getValueSize(); - image.addEventListener( 'progress', function ( event ) { + if (targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { + targetOffset = targetValueSize / 3; + } - onProgress( event ); + var lastIndex = referenceTrack.times.length - 1; + var referenceValue = void 0; // Find the value to subtract out of the track - }, false ); + if (referenceTime <= referenceTrack.times[0]) { + // Reference frame is earlier than the first keyframe, so just use the first keyframe + var startIndex = referenceOffset; + var endIndex = referenceValueSize - referenceOffset; + referenceValue = AnimationUtils.arraySlice(referenceTrack.values, startIndex, endIndex); + } else if (referenceTime >= referenceTrack.times[lastIndex]) { + // Reference frame is after the last keyframe, so just use the last keyframe + var _startIndex = lastIndex * referenceValueSize + referenceOffset; - } + var _endIndex = _startIndex + referenceValueSize - referenceOffset; - if ( onError !== undefined ) { + referenceValue = AnimationUtils.arraySlice(referenceTrack.values, _startIndex, _endIndex); + } else { + // Interpolate to the reference value + var interpolant = referenceTrack.createInterpolant(); + var _startIndex2 = referenceOffset; - image.addEventListener( 'error', function ( event ) { + var _endIndex2 = referenceValueSize - referenceOffset; - onError( event ); + interpolant.evaluate(referenceTime); + referenceValue = AnimationUtils.arraySlice(interpolant.resultBuffer, _startIndex2, _endIndex2); + } // Conjugate the quaternion - }, false ); - - } - - if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin; - - image.src = url; - - scope.manager.itemStart( url ); - - return image; - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - - } - -} - -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.JSONLoader = function ( showStatus ) { - - THREE.Loader.call( this, showStatus ); - - this.withCredentials = false; - -}; - -THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype ); - -THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) { - - var scope = this; - - // todo: unify load API to for easier SceneLoader use - - texturePath = texturePath && ( typeof texturePath === "string" ) ? texturePath : this.extractUrlBase( url ); - - this.onLoadStart(); - this.loadAjaxJSON( this, url, callback, texturePath ); - -}; - -THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, callbackProgress ) { - - var xhr = new XMLHttpRequest(); - - var length = 0; - - xhr.onreadystatechange = function () { - - if ( xhr.readyState === xhr.DONE ) { - - if ( xhr.status === 200 || xhr.status === 0 ) { - - if ( xhr.responseText ) { - - var json = JSON.parse( xhr.responseText ); - - if ( json.metadata !== undefined && json.metadata.type === 'scene' ) { - - console.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' ); - return; - - } - - var result = context.parse( json, texturePath ); - callback( result.geometry, result.materials ); - - } else { - - console.error( 'THREE.JSONLoader: "' + url + '" seems to be unreachable or the file is empty.' ); - - } - - // in context of more complex asset initialization - // do not block on single failed file - // maybe should go even one more level up - - context.onLoadComplete(); - - } else { - - console.error( 'THREE.JSONLoader: Couldn\'t load "' + url + '" (' + xhr.status + ')' ); - - } - - } else if ( xhr.readyState === xhr.LOADING ) { - - if ( callbackProgress ) { - - if ( length === 0 ) { - - length = xhr.getResponseHeader( 'Content-Length' ); - - } - - callbackProgress( { total: length, loaded: xhr.responseText.length } ); - - } - - } else if ( xhr.readyState === xhr.HEADERS_RECEIVED ) { - - if ( callbackProgress !== undefined ) { - - length = xhr.getResponseHeader( "Content-Length" ); - - } - - } - - }; - - xhr.open( "GET", url, true ); - xhr.withCredentials = this.withCredentials; - xhr.send( null ); - -}; - -THREE.JSONLoader.prototype.parse = function ( json, texturePath ) { - - var scope = this, - geometry = new THREE.Geometry(), - scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0; - - parseModel( scale ); - - parseSkin(); - parseMorphing( scale ); - - geometry.computeFaceNormals(); - geometry.computeBoundingSphere(); - - function parseModel( scale ) { - - function isBitSet( value, position ) { - - return value & ( 1 << position ); - - } - - var i, j, fi, - - offset, zLength, - - colorIndex, normalIndex, uvIndex, materialIndex, - - type, - isQuad, - hasMaterial, - hasFaceVertexUv, - hasFaceNormal, hasFaceVertexNormal, - hasFaceColor, hasFaceVertexColor, - - vertex, face, faceA, faceB, color, hex, normal, - - uvLayer, uv, u, v, - - faces = json.faces, - vertices = json.vertices, - normals = json.normals, - colors = json.colors, - - nUvLayers = 0; - - if ( json.uvs !== undefined ) { - - // disregard empty arrays - - for ( i = 0; i < json.uvs.length; i++ ) { - - if ( json.uvs[ i ].length ) nUvLayers ++; - - } - - for ( i = 0; i < nUvLayers; i++ ) { - - geometry.faceVertexUvs[ i ] = []; - - } - - } - - offset = 0; - zLength = vertices.length; - - while ( offset < zLength ) { - - vertex = new THREE.Vector3(); - - vertex.x = vertices[ offset ++ ] * scale; - vertex.y = vertices[ offset ++ ] * scale; - vertex.z = vertices[ offset ++ ] * scale; - - geometry.vertices.push( vertex ); - - } - - offset = 0; - zLength = faces.length; - - while ( offset < zLength ) { - - type = faces[ offset ++ ]; - - - isQuad = isBitSet( type, 0 ); - hasMaterial = isBitSet( type, 1 ); - hasFaceVertexUv = isBitSet( type, 3 ); - hasFaceNormal = isBitSet( type, 4 ); - hasFaceVertexNormal = isBitSet( type, 5 ); - hasFaceColor = isBitSet( type, 6 ); - hasFaceVertexColor = isBitSet( type, 7 ); - - // console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor); - - if ( isQuad ) { - - faceA = new THREE.Face3(); - faceA.a = faces[ offset ]; - faceA.b = faces[ offset + 1 ]; - faceA.c = faces[ offset + 3 ]; - - faceB = new THREE.Face3(); - faceB.a = faces[ offset + 1 ]; - faceB.b = faces[ offset + 2 ]; - faceB.c = faces[ offset + 3 ]; - - offset += 4; - - if ( hasMaterial ) { - - materialIndex = faces[ offset ++ ]; - faceA.materialIndex = materialIndex; - faceB.materialIndex = materialIndex; - - } - - // to get face <=> uv index correspondence - - fi = geometry.faces.length; - - if ( hasFaceVertexUv ) { - - for ( i = 0; i < nUvLayers; i++ ) { - - uvLayer = json.uvs[ i ]; - - geometry.faceVertexUvs[ i ][ fi ] = []; - geometry.faceVertexUvs[ i ][ fi + 1 ] = [] - - for ( j = 0; j < 4; j ++ ) { - - uvIndex = faces[ offset ++ ]; - - u = uvLayer[ uvIndex * 2 ]; - v = uvLayer[ uvIndex * 2 + 1 ]; - - uv = new THREE.Vector2( u, v ); - - if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv ); - if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv ); - - } - - } - - } - - if ( hasFaceNormal ) { - - normalIndex = faces[ offset ++ ] * 3; - - faceA.normal.set( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); - - faceB.normal.copy( faceA.normal ); - - } - - if ( hasFaceVertexNormal ) { - - for ( i = 0; i < 4; i++ ) { - - normalIndex = faces[ offset ++ ] * 3; - - normal = new THREE.Vector3( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); - - - if ( i !== 2 ) faceA.vertexNormals.push( normal ); - if ( i !== 0 ) faceB.vertexNormals.push( normal ); - - } - - } - - - if ( hasFaceColor ) { - - colorIndex = faces[ offset ++ ]; - hex = colors[ colorIndex ]; - - faceA.color.setHex( hex ); - faceB.color.setHex( hex ); - - } - - - if ( hasFaceVertexColor ) { - - for ( i = 0; i < 4; i++ ) { - - colorIndex = faces[ offset ++ ]; - hex = colors[ colorIndex ]; - - if ( i !== 2 ) faceA.vertexColors.push( new THREE.Color( hex ) ); - if ( i !== 0 ) faceB.vertexColors.push( new THREE.Color( hex ) ); - - } - - } - - geometry.faces.push( faceA ); - geometry.faces.push( faceB ); - - } else { - - face = new THREE.Face3(); - face.a = faces[ offset ++ ]; - face.b = faces[ offset ++ ]; - face.c = faces[ offset ++ ]; - - if ( hasMaterial ) { - - materialIndex = faces[ offset ++ ]; - face.materialIndex = materialIndex; - - } - - // to get face <=> uv index correspondence - - fi = geometry.faces.length; - - if ( hasFaceVertexUv ) { - - for ( i = 0; i < nUvLayers; i++ ) { - - uvLayer = json.uvs[ i ]; - - geometry.faceVertexUvs[ i ][ fi ] = []; - - for ( j = 0; j < 3; j ++ ) { - - uvIndex = faces[ offset ++ ]; - - u = uvLayer[ uvIndex * 2 ]; - v = uvLayer[ uvIndex * 2 + 1 ]; - - uv = new THREE.Vector2( u, v ); - - geometry.faceVertexUvs[ i ][ fi ].push( uv ); - - } - - } - - } - - if ( hasFaceNormal ) { - - normalIndex = faces[ offset ++ ] * 3; - - face.normal.set( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); - - } - - if ( hasFaceVertexNormal ) { - - for ( i = 0; i < 3; i++ ) { - - normalIndex = faces[ offset ++ ] * 3; - - normal = new THREE.Vector3( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); - - face.vertexNormals.push( normal ); - - } - - } - - - if ( hasFaceColor ) { - - colorIndex = faces[ offset ++ ]; - face.color.setHex( colors[ colorIndex ] ); - - } - - - if ( hasFaceVertexColor ) { - - for ( i = 0; i < 3; i++ ) { - - colorIndex = faces[ offset ++ ]; - face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) ); - - } - - } - - geometry.faces.push( face ); - - } - - } - - }; - - function parseSkin() { - var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2; - - if ( json.skinWeights ) { - - for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) { - - var x = json.skinWeights[ i ]; - var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0; - var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0; - var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0; - - geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) ); - - } - - } - - if ( json.skinIndices ) { - - for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) { - - var a = json.skinIndices[ i ]; - var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0; - var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0; - var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0; - - geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) ); - - } - - } - - geometry.bones = json.bones; - - if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) { - - console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + - geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' ); - - } - - - // could change this to json.animations[0] or remove completely - - geometry.animation = json.animation; - geometry.animations = json.animations; - - }; - - function parseMorphing( scale ) { - - if ( json.morphTargets !== undefined ) { - - var i, l, v, vl, dstVertices, srcVertices; - - for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) { - - geometry.morphTargets[ i ] = {}; - geometry.morphTargets[ i ].name = json.morphTargets[ i ].name; - geometry.morphTargets[ i ].vertices = []; - - dstVertices = geometry.morphTargets[ i ].vertices; - srcVertices = json.morphTargets [ i ].vertices; - - for( v = 0, vl = srcVertices.length; v < vl; v += 3 ) { - - var vertex = new THREE.Vector3(); - vertex.x = srcVertices[ v ] * scale; - vertex.y = srcVertices[ v + 1 ] * scale; - vertex.z = srcVertices[ v + 2 ] * scale; - - dstVertices.push( vertex ); - - } - - } - - } - - if ( json.morphColors !== undefined ) { - - var i, l, c, cl, dstColors, srcColors, color; - - for ( i = 0, l = json.morphColors.length; i < l; i++ ) { - - geometry.morphColors[ i ] = {}; - geometry.morphColors[ i ].name = json.morphColors[ i ].name; - geometry.morphColors[ i ].colors = []; - - dstColors = geometry.morphColors[ i ].colors; - srcColors = json.morphColors [ i ].colors; - - for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) { - - color = new THREE.Color( 0xffaa00 ); - color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] ); - dstColors.push( color ); - - } - - } - - } - - }; - - if ( json.materials === undefined || json.materials.length === 0 ) { - - return { geometry: geometry }; - - } else { - - var materials = this.initMaterials( json.materials, texturePath ); - - if ( this.needsTangents( materials ) ) { - - geometry.computeTangents(); - - } - - return { geometry: geometry, materials: materials }; - - } - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.LoadingManager = function ( onLoad, onProgress, onError ) { - - var scope = this; - - var loaded = 0, total = 0; - - this.onLoad = onLoad; - this.onProgress = onProgress; - this.onError = onError; - - this.itemStart = function ( url ) { - - total ++; - }; + if (referenceTrackType === 'quaternion') { + var referenceQuat = new Quaternion().fromArray(referenceValue).normalize().conjugate(); + referenceQuat.toArray(referenceValue); + } // Subtract the reference value from all of the track values - this.itemEnd = function ( url ) { - loaded ++; + var numTimes = targetTrack.times.length; - if ( scope.onProgress !== undefined ) { + for (var j = 0; j < numTimes; ++j) { + var valueStart = j * targetValueSize + targetOffset; - scope.onProgress( url, loaded, total ); + if (referenceTrackType === 'quaternion') { + // Multiply the conjugate for quaternion track types + Quaternion.multiplyQuaternionsFlat(targetTrack.values, valueStart, referenceValue, 0, targetTrack.values, valueStart); + } else { + var valueEnd = targetValueSize - targetOffset * 2; // Subtract each value for all other numeric track types - } + for (var k = 0; k < valueEnd; ++k) { + targetTrack.values[valueStart + k] -= referenceValue[k]; + } + } + } + }; - if ( loaded === total && scope.onLoad !== undefined ) { + for (var i = 0; i < numTracks; ++i) { + var _ret = _loop(i); - scope.onLoad(); + if (_ret === "continue") continue; + } + targetClip.blendMode = AdditiveAnimationBlendMode; + return targetClip; } - }; -}; - -THREE.DefaultLoadingManager = new THREE.LoadingManager(); - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.BufferGeometryLoader = function ( manager ) { - - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - -}; - -THREE.BufferGeometryLoader.prototype = { - - constructor: THREE.BufferGeometryLoader, - - load: function ( url, onLoad, onProgress, onError ) { - - var scope = this; - - var loader = new THREE.XHRLoader(); - loader.setCrossOrigin( this.crossOrigin ); - loader.load( url, function ( text ) { - - onLoad( scope.parse( JSON.parse( text ) ) ); - - } ); - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - - }, - - parse: function ( json ) { - - var geometry = new THREE.BufferGeometry(); - - var attributes = json.attributes; - var offsets = json.offsets; - var boundingSphere = json.boundingSphere; - - for ( var key in attributes ) { - - var attribute = attributes[ key ]; - - geometry.attributes[ key ] = { - itemSize: attribute.itemSize, - array: new self[ attribute.type ]( attribute.array ) - } - - } - - if ( offsets !== undefined ) { - - geometry.offsets = JSON.parse( JSON.stringify( offsets ) ); - - } - - if ( boundingSphere !== undefined ) { - - geometry.boundingSphere = new THREE.Sphere( - new THREE.Vector3().fromArray( boundingSphere.center !== undefined ? boundingSphere.center : [ 0, 0, 0 ] ), - boundingSphere.radius - ); - - } - - return geometry; - - } - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.MaterialLoader = function ( manager ) { - - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - -}; - -THREE.MaterialLoader.prototype = { - - constructor: THREE.MaterialLoader, - - load: function ( url, onLoad, onProgress, onError ) { - - var scope = this; - - var loader = new THREE.XHRLoader(); - loader.setCrossOrigin( this.crossOrigin ); - loader.load( url, function ( text ) { - - onLoad( scope.parse( JSON.parse( text ) ) ); - - } ); - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - - }, - - parse: function ( json ) { - - var material = new THREE[ json.type ]; - - if ( json.color !== undefined ) material.color.setHex( json.color ); - if ( json.ambient !== undefined ) material.ambient.setHex( json.ambient ); - if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive ); - if ( json.specular !== undefined ) material.specular.setHex( json.specular ); - if ( json.shininess !== undefined ) material.shininess = json.shininess; - if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors; - if ( json.blending !== undefined ) material.blending = json.blending; - if ( json.side !== undefined ) material.side = json.side; - if ( json.opacity !== undefined ) material.opacity = json.opacity; - if ( json.transparent !== undefined ) material.transparent = json.transparent; - if ( json.wireframe !== undefined ) material.wireframe = json.wireframe; - - if ( json.materials !== undefined ) { - - for ( var i = 0, l = json.materials.length; i < l; i ++ ) { - - material.materials.push( this.parse( json.materials[ i ] ) ); - - } - - } - - return material; - - } - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.ObjectLoader = function ( manager ) { - - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - -}; - -THREE.ObjectLoader.prototype = { - - constructor: THREE.ObjectLoader, - - load: function ( url, onLoad, onProgress, onError ) { + /** + * Abstract base class of interpolants over parametric samples. + * + * The parameter domain is one dimensional, typically the time or a path + * along a curve defined by the data. + * + * The sample values can have any dimensionality and derived classes may + * apply special interpretations to the data. + * + * This class provides the interval seek in a Template Method, deferring + * the actual interpolation to derived classes. + * + * Time complexity is O(1) for linear access crossing at most two points + * and O(log N) for random access, where N is the number of positions. + * + * References: + * + * http://www.oodesign.com/template-method-pattern.html + * + */ + function Interpolant(parameterPositions, sampleValues, sampleSize, resultBuffer) { + this.parameterPositions = parameterPositions; + this._cachedIndex = 0; + this.resultBuffer = resultBuffer !== undefined ? resultBuffer : new sampleValues.constructor(sampleSize); + this.sampleValues = sampleValues; + this.valueSize = sampleSize; + } + + Object.assign(Interpolant.prototype, { + evaluate: function evaluate(t) { + var pp = this.parameterPositions; + var i1 = this._cachedIndex, + t1 = pp[i1], + t0 = pp[i1 - 1]; + + validate_interval: { + seek: { + var right; + + linear_scan: { + //- See http://jsperf.com/comparison-to-undefined/3 + //- slower code: + //- + //- if ( t >= t1 || t1 === undefined ) { + forward_scan: if (!(t < t1)) { + for (var giveUpAt = i1 + 2;;) { + if (t1 === undefined) { + if (t < t0) break forward_scan; // after end + + i1 = pp.length; + this._cachedIndex = i1; + return this.afterEnd_(i1 - 1, t, t0); + } - var scope = this; + if (i1 === giveUpAt) break; // this loop - var loader = new THREE.XHRLoader( scope.manager ); - loader.setCrossOrigin( this.crossOrigin ); - loader.load( url, function ( text ) { + t0 = t1; + t1 = pp[++i1]; - onLoad( scope.parse( JSON.parse( text ) ) ); + if (t < t1) { + // we have arrived at the sought interval + break seek; + } + } // prepare binary search on the right side of the index - } ); - }, + right = pp.length; + break linear_scan; + } //- slower code: + //- if ( t < t0 || t0 === undefined ) { - setCrossOrigin: function ( value ) { - this.crossOrigin = value; + if (!(t >= t0)) { + // looping? + var t1global = pp[1]; - }, + if (t < t1global) { + i1 = 2; // + 1, using the scan for the details - parse: function ( json ) { + t0 = t1global; + } // linear reverse scan - var geometries = this.parseGeometries( json.geometries ); - var materials = this.parseMaterials( json.materials ); - var object = this.parseObject( json.object, geometries, materials ); - return object; + for (var _giveUpAt = i1 - 2;;) { + if (t0 === undefined) { + // before start + this._cachedIndex = 0; + return this.beforeStart_(0, t, t1); + } - }, + if (i1 === _giveUpAt) break; // this loop - parseGeometries: function ( json ) { + t1 = t0; + t0 = pp[--i1 - 1]; - var geometries = {}; + if (t >= t0) { + // we have arrived at the sought interval + break seek; + } + } // prepare binary search on the left side of the index - if ( json !== undefined ) { - var geometryLoader = new THREE.JSONLoader(); - var bufferGeometryLoader = new THREE.BufferGeometryLoader(); + right = i1; + i1 = 0; + break linear_scan; + } // the interval is valid - for ( var i = 0, l = json.length; i < l; i ++ ) { - var geometry; - var data = json[ i ]; + break validate_interval; + } // linear scan + // binary search - switch ( data.type ) { - case 'PlaneGeometry': + while (i1 < right) { + var mid = i1 + right >>> 1; - geometry = new THREE.PlaneGeometry( - data.width, - data.height, - data.widthSegments, - data.heightSegments - ); + if (t < pp[mid]) { + right = mid; + } else { + i1 = mid + 1; + } + } - break; + t1 = pp[i1]; + t0 = pp[i1 - 1]; // check boundary cases, again - case 'BoxGeometry': - case 'CubeGeometry': // DEPRECATED + if (t0 === undefined) { + this._cachedIndex = 0; + return this.beforeStart_(0, t, t1); + } - geometry = new THREE.BoxGeometry( - data.width, - data.height, - data.depth, - data.widthSegments, - data.heightSegments, - data.depthSegments - ); + if (t1 === undefined) { + i1 = pp.length; + this._cachedIndex = i1; + return this.afterEnd_(i1 - 1, t0, t); + } + } // seek - break; - case 'CircleGeometry': + this._cachedIndex = i1; + this.intervalChanged_(i1, t0, t1); + } // validate_interval - geometry = new THREE.CircleGeometry( - data.radius, - data.segments - ); - break; + return this.interpolate_(i1, t0, t, t1); + }, + settings: null, + // optional, subclass-specific settings structure + // Note: The indirection allows central control of many interpolants. + // --- Protected interface + DefaultSettings_: {}, + getSettings_: function getSettings_() { + return this.settings || this.DefaultSettings_; + }, + copySampleValue_: function copySampleValue_(index) { + // copies a sample value to the result buffer + var result = this.resultBuffer, + values = this.sampleValues, + stride = this.valueSize, + offset = index * stride; - case 'CylinderGeometry': + for (var i = 0; i !== stride; ++i) { + result[i] = values[offset + i]; + } - geometry = new THREE.CylinderGeometry( - data.radiusTop, - data.radiusBottom, - data.height, - data.radialSegments, - data.heightSegments, - data.openEnded - ); + return result; + }, + // Template methods for derived classes: + interpolate_: function interpolate_() + /* i1, t0, t, t1 */ + { + throw new Error('call to abstract method'); // implementations shall return this.resultBuffer + }, + intervalChanged_: function intervalChanged_() + /* i1, t0, t1 */ + {// empty + } + }); // DECLARE ALIAS AFTER assign prototype - break; + Object.assign(Interpolant.prototype, { + //( 0, t, t0 ), returns this.resultBuffer + beforeStart_: Interpolant.prototype.copySampleValue_, + //( N-1, tN-1, t ), returns this.resultBuffer + afterEnd_: Interpolant.prototype.copySampleValue_ + }); - case 'SphereGeometry': + /** + * Fast and simple cubic spline interpolant. + * + * It was derived from a Hermitian construction setting the first derivative + * at each sample position to the linear slope between neighboring positions + * over their parameter interval. + */ - geometry = new THREE.SphereGeometry( - data.radius, - data.widthSegments, - data.heightSegments, - data.phiStart, - data.phiLength, - data.thetaStart, - data.thetaLength - ); + function CubicInterpolant(parameterPositions, sampleValues, sampleSize, resultBuffer) { + Interpolant.call(this, parameterPositions, sampleValues, sampleSize, resultBuffer); + this._weightPrev = -0; + this._offsetPrev = -0; + this._weightNext = -0; + this._offsetNext = -0; + } + CubicInterpolant.prototype = Object.assign(Object.create(Interpolant.prototype), { + constructor: CubicInterpolant, + DefaultSettings_: { + endingStart: ZeroCurvatureEnding, + endingEnd: ZeroCurvatureEnding + }, + intervalChanged_: function intervalChanged_(i1, t0, t1) { + var pp = this.parameterPositions; + var iPrev = i1 - 2, + iNext = i1 + 1, + tPrev = pp[iPrev], + tNext = pp[iNext]; + + if (tPrev === undefined) { + switch (this.getSettings_().endingStart) { + case ZeroSlopeEnding: + // f'(t0) = 0 + iPrev = i1; + tPrev = 2 * t0 - t1; break; - case 'IcosahedronGeometry': - - geometry = new THREE.IcosahedronGeometry( - data.radius, - data.detail - ); - + case WrapAroundEnding: + // use the other end of the curve + iPrev = pp.length - 2; + tPrev = t0 + pp[iPrev] - pp[iPrev + 1]; break; - case 'TorusGeometry': + default: + // ZeroCurvatureEnding + // f''(t0) = 0 a.k.a. Natural Spline + iPrev = i1; + tPrev = t1; + } + } - geometry = new THREE.TorusGeometry( - data.radius, - data.tube, - data.radialSegments, - data.tubularSegments, - data.arc - ); + if (tNext === undefined) { + switch (this.getSettings_().endingEnd) { + case ZeroSlopeEnding: + // f'(tN) = 0 + iNext = i1; + tNext = 2 * t1 - t0; + break; + case WrapAroundEnding: + // use the other end of the curve + iNext = 1; + tNext = t1 + pp[1] - pp[0]; break; - case 'TorusKnotGeometry': + default: + // ZeroCurvatureEnding + // f''(tN) = 0, a.k.a. Natural Spline + iNext = i1 - 1; + tNext = t0; + } + } + + var halfDt = (t1 - t0) * 0.5, + stride = this.valueSize; + this._weightPrev = halfDt / (t0 - tPrev); + this._weightNext = halfDt / (tNext - t1); + this._offsetPrev = iPrev * stride; + this._offsetNext = iNext * stride; + }, + interpolate_: function interpolate_(i1, t0, t, t1) { + var result = this.resultBuffer, + values = this.sampleValues, + stride = this.valueSize, + o1 = i1 * stride, + o0 = o1 - stride, + oP = this._offsetPrev, + oN = this._offsetNext, + wP = this._weightPrev, + wN = this._weightNext, + p = (t - t0) / (t1 - t0), + pp = p * p, + ppp = pp * p; // evaluate polynomials + + var sP = -wP * ppp + 2 * wP * pp - wP * p; + var s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p + 1; + var s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p; + var sN = wN * ppp - wN * pp; // combine data linearly + + for (var i = 0; i !== stride; ++i) { + result[i] = sP * values[oP + i] + s0 * values[o0 + i] + s1 * values[o1 + i] + sN * values[oN + i]; + } - geometry = new THREE.TorusKnotGeometry( - data.radius, - data.tube, - data.radialSegments, - data.tubularSegments, - data.p, - data.q, - data.heightScale - ); + return result; + } + }); - break; + function LinearInterpolant(parameterPositions, sampleValues, sampleSize, resultBuffer) { + Interpolant.call(this, parameterPositions, sampleValues, sampleSize, resultBuffer); + } - case 'BufferGeometry': + LinearInterpolant.prototype = Object.assign(Object.create(Interpolant.prototype), { + constructor: LinearInterpolant, + interpolate_: function interpolate_(i1, t0, t, t1) { + var result = this.resultBuffer, + values = this.sampleValues, + stride = this.valueSize, + offset1 = i1 * stride, + offset0 = offset1 - stride, + weight1 = (t - t0) / (t1 - t0), + weight0 = 1 - weight1; - geometry = bufferGeometryLoader.parse( data.data ); + for (var i = 0; i !== stride; ++i) { + result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1; + } - break; + return result; + } + }); - case 'Geometry': + /** + * + * Interpolant that evaluates to the sample value at the position preceeding + * the parameter. + */ - geometry = geometryLoader.parse( data.data ).geometry; + function DiscreteInterpolant(parameterPositions, sampleValues, sampleSize, resultBuffer) { + Interpolant.call(this, parameterPositions, sampleValues, sampleSize, resultBuffer); + } - break; + DiscreteInterpolant.prototype = Object.assign(Object.create(Interpolant.prototype), { + constructor: DiscreteInterpolant, + interpolate_: function interpolate_(i1 + /*, t0, t, t1 */ + ) { + return this.copySampleValue_(i1 - 1); + } + }); - } + function KeyframeTrack(name, times, values, interpolation) { + if (name === undefined) throw new Error('THREE.KeyframeTrack: track name is undefined'); + if (times === undefined || times.length === 0) throw new Error('THREE.KeyframeTrack: no keyframes in track named ' + name); + this.name = name; + this.times = AnimationUtils.convertArray(times, this.TimeBufferType); + this.values = AnimationUtils.convertArray(values, this.ValueBufferType); + this.setInterpolation(interpolation || this.DefaultInterpolation); + } // Static methods - geometry.uuid = data.uuid; - if ( data.name !== undefined ) geometry.name = data.name; + Object.assign(KeyframeTrack, { + // Serialization (in static context, because of constructor invocation + // and automatic invocation of .toJSON): + toJSON: function toJSON(track) { + var trackType = track.constructor; + var json; // derived classes can define a static toJSON method - geometries[ data.uuid ] = geometry; + if (trackType.toJSON !== undefined) { + json = trackType.toJSON(track); + } else { + // by default, we assume the data can be serialized as-is + json = { + 'name': track.name, + 'times': AnimationUtils.convertArray(track.times, Array), + 'values': AnimationUtils.convertArray(track.values, Array) + }; + var interpolation = track.getInterpolation(); + if (interpolation !== track.DefaultInterpolation) { + json.interpolation = interpolation; + } } + json.type = track.ValueTypeName; // mandatory + + return json; } + }); + Object.assign(KeyframeTrack.prototype, { + constructor: KeyframeTrack, + TimeBufferType: Float32Array, + ValueBufferType: Float32Array, + DefaultInterpolation: InterpolateLinear, + InterpolantFactoryMethodDiscrete: function InterpolantFactoryMethodDiscrete(result) { + return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result); + }, + InterpolantFactoryMethodLinear: function InterpolantFactoryMethodLinear(result) { + return new LinearInterpolant(this.times, this.values, this.getValueSize(), result); + }, + InterpolantFactoryMethodSmooth: function InterpolantFactoryMethodSmooth(result) { + return new CubicInterpolant(this.times, this.values, this.getValueSize(), result); + }, + setInterpolation: function setInterpolation(interpolation) { + var factoryMethod; - return geometries; + switch (interpolation) { + case InterpolateDiscrete: + factoryMethod = this.InterpolantFactoryMethodDiscrete; + break; - }, + case InterpolateLinear: + factoryMethod = this.InterpolantFactoryMethodLinear; + break; - parseMaterials: function ( json ) { + case InterpolateSmooth: + factoryMethod = this.InterpolantFactoryMethodSmooth; + break; + } - var materials = {}; + if (factoryMethod === undefined) { + var message = "unsupported interpolation for " + this.ValueTypeName + " keyframe track named " + this.name; - if ( json !== undefined ) { + if (this.createInterpolant === undefined) { + // fall back to default, unless the default itself is messed up + if (interpolation !== this.DefaultInterpolation) { + this.setInterpolation(this.DefaultInterpolation); + } else { + throw new Error(message); // fatal, in this case + } + } - var loader = new THREE.MaterialLoader(); + console.warn('THREE.KeyframeTrack:', message); + return this; + } - for ( var i = 0, l = json.length; i < l; i ++ ) { + this.createInterpolant = factoryMethod; + return this; + }, + getInterpolation: function getInterpolation() { + switch (this.createInterpolant) { + case this.InterpolantFactoryMethodDiscrete: + return InterpolateDiscrete; - var data = json[ i ]; - var material = loader.parse( data ); + case this.InterpolantFactoryMethodLinear: + return InterpolateLinear; - material.uuid = data.uuid; + case this.InterpolantFactoryMethodSmooth: + return InterpolateSmooth; + } + }, + getValueSize: function getValueSize() { + return this.values.length / this.times.length; + }, + // move all keyframes either forwards or backwards in time + shift: function shift(timeOffset) { + if (timeOffset !== 0.0) { + var times = this.times; - if ( data.name !== undefined ) material.name = data.name; + for (var i = 0, n = times.length; i !== n; ++i) { + times[i] += timeOffset; + } + } - materials[ data.uuid ] = material; + return this; + }, + // scale all keyframe times by a factor (useful for frame <-> seconds conversions) + scale: function scale(timeScale) { + if (timeScale !== 1.0) { + var times = this.times; + for (var i = 0, n = times.length; i !== n; ++i) { + times[i] *= timeScale; + } } - } + return this; + }, + // removes keyframes before and after animation without changing any values within the range [startTime, endTime]. + // IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values + trim: function trim(startTime, endTime) { + var times = this.times, + nKeys = times.length; + var from = 0, + to = nKeys - 1; - return materials; + while (from !== nKeys && times[from] < startTime) { + ++from; + } - }, + while (to !== -1 && times[to] > endTime) { + --to; + } - parseObject: function () { + ++to; // inclusive -> exclusive bound - var matrix = new THREE.Matrix4(); + if (from !== 0 || to !== nKeys) { + // empty tracks are forbidden, so keep at least one keyframe + if (from >= to) { + to = Math.max(to, 1); + from = to - 1; + } - return function ( data, geometries, materials ) { + var stride = this.getValueSize(); + this.times = AnimationUtils.arraySlice(times, from, to); + this.values = AnimationUtils.arraySlice(this.values, from * stride, to * stride); + } - var object; + return this; + }, + // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable + validate: function validate() { + var valid = true; + var valueSize = this.getValueSize(); - switch ( data.type ) { + if (valueSize - Math.floor(valueSize) !== 0) { + console.error('THREE.KeyframeTrack: Invalid value size in track.', this); + valid = false; + } - case 'Scene': + var times = this.times, + values = this.values, + nKeys = times.length; - object = new THREE.Scene(); + if (nKeys === 0) { + console.error('THREE.KeyframeTrack: Track is empty.', this); + valid = false; + } - break; + var prevTime = null; - case 'PerspectiveCamera': + for (var i = 0; i !== nKeys; i++) { + var currTime = times[i]; - object = new THREE.PerspectiveCamera( data.fov, data.aspect, data.near, data.far ); + if (typeof currTime === 'number' && isNaN(currTime)) { + console.error('THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime); + valid = false; + break; + } + if (prevTime !== null && prevTime > currTime) { + console.error('THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime); + valid = false; break; + } - case 'OrthographicCamera': + prevTime = currTime; + } - object = new THREE.OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far ); + if (values !== undefined) { + if (AnimationUtils.isTypedArray(values)) { + for (var _i = 0, n = values.length; _i !== n; ++_i) { + var value = values[_i]; - break; + if (isNaN(value)) { + console.error('THREE.KeyframeTrack: Value is not a valid number.', this, _i, value); + valid = false; + break; + } + } + } + } - case 'AmbientLight': + return valid; + }, + // removes equivalent sequential keys as common in morph target sequences + // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) + optimize: function optimize() { + // times or values may be shared with other tracks, so overwriting is unsafe + var times = AnimationUtils.arraySlice(this.times), + values = AnimationUtils.arraySlice(this.values), + stride = this.getValueSize(), + smoothInterpolation = this.getInterpolation() === InterpolateSmooth, + lastIndex = times.length - 1; + var writeIndex = 1; + + for (var i = 1; i < lastIndex; ++i) { + var keep = false; + var time = times[i]; + var timeNext = times[i + 1]; // remove adjacent keyframes scheduled at the same time + + if (time !== timeNext && (i !== 1 || time !== time[0])) { + if (!smoothInterpolation) { + // remove unnecessary keyframes same as their neighbors + var offset = i * stride, + offsetP = offset - stride, + offsetN = offset + stride; + + for (var j = 0; j !== stride; ++j) { + var value = values[offset + j]; + + if (value !== values[offsetP + j] || value !== values[offsetN + j]) { + keep = true; + break; + } + } + } else { + keep = true; + } + } // in-place compaction - object = new THREE.AmbientLight( data.color ); - break; + if (keep) { + if (i !== writeIndex) { + times[writeIndex] = times[i]; + var readOffset = i * stride, + writeOffset = writeIndex * stride; - case 'DirectionalLight': + for (var _j = 0; _j !== stride; ++_j) { + values[writeOffset + _j] = values[readOffset + _j]; + } + } - object = new THREE.DirectionalLight( data.color, data.intensity ); + ++writeIndex; + } + } // flush last keyframe (compaction looks ahead) - break; - case 'PointLight': + if (lastIndex > 0) { + times[writeIndex] = times[lastIndex]; - object = new THREE.PointLight( data.color, data.intensity, data.distance ); + for (var _readOffset = lastIndex * stride, _writeOffset = writeIndex * stride, _j2 = 0; _j2 !== stride; ++_j2) { + values[_writeOffset + _j2] = values[_readOffset + _j2]; + } - break; + ++writeIndex; + } - case 'SpotLight': + if (writeIndex !== times.length) { + this.times = AnimationUtils.arraySlice(times, 0, writeIndex); + this.values = AnimationUtils.arraySlice(values, 0, writeIndex * stride); + } else { + this.times = times; + this.values = values; + } - object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent ); + return this; + }, + clone: function clone() { + var times = AnimationUtils.arraySlice(this.times, 0); + var values = AnimationUtils.arraySlice(this.values, 0); + var TypedKeyframeTrack = this.constructor; + var track = new TypedKeyframeTrack(this.name, times, values); // Interpolant argument to constructor is not saved, so copy the factory method directly. - break; + track.createInterpolant = this.createInterpolant; + return track; + } + }); - case 'HemisphereLight': + /** + * A Track of Boolean keyframe values. + */ - object = new THREE.HemisphereLight( data.color, data.groundColor, data.intensity ); + function BooleanKeyframeTrack(name, times, values) { + KeyframeTrack.call(this, name, times, values); + } - break; + BooleanKeyframeTrack.prototype = Object.assign(Object.create(KeyframeTrack.prototype), { + constructor: BooleanKeyframeTrack, + ValueTypeName: 'bool', + ValueBufferType: Array, + DefaultInterpolation: InterpolateDiscrete, + InterpolantFactoryMethodLinear: undefined, + InterpolantFactoryMethodSmooth: undefined // Note: Actually this track could have a optimized / compressed + // representation of a single value and a custom interpolant that + // computes "firstValue ^ isOdd( index )". - case 'Mesh': + }); - var geometry = geometries[ data.geometry ]; - var material = materials[ data.material ]; + /** + * A Track of keyframe values that represent color. + */ - if ( geometry === undefined ) { + function ColorKeyframeTrack(name, times, values, interpolation) { + KeyframeTrack.call(this, name, times, values, interpolation); + } - console.error( 'THREE.ObjectLoader: Undefined geometry ' + data.geometry ); + ColorKeyframeTrack.prototype = Object.assign(Object.create(KeyframeTrack.prototype), { + constructor: ColorKeyframeTrack, + ValueTypeName: 'color' // ValueBufferType is inherited + // DefaultInterpolation is inherited + // Note: Very basic implementation and nothing special yet. + // However, this is the place for color space parameterization. - } + }); - if ( material === undefined ) { + /** + * A Track of numeric keyframe values. + */ - console.error( 'THREE.ObjectLoader: Undefined material ' + data.material ); + function NumberKeyframeTrack(name, times, values, interpolation) { + KeyframeTrack.call(this, name, times, values, interpolation); + } - } + NumberKeyframeTrack.prototype = Object.assign(Object.create(KeyframeTrack.prototype), { + constructor: NumberKeyframeTrack, + ValueTypeName: 'number' // ValueBufferType is inherited + // DefaultInterpolation is inherited - object = new THREE.Mesh( geometry, material ); + }); - break; + /** + * Spherical linear unit quaternion interpolant. + */ - case 'Sprite': + function QuaternionLinearInterpolant(parameterPositions, sampleValues, sampleSize, resultBuffer) { + Interpolant.call(this, parameterPositions, sampleValues, sampleSize, resultBuffer); + } - var material = materials[ data.material ]; + QuaternionLinearInterpolant.prototype = Object.assign(Object.create(Interpolant.prototype), { + constructor: QuaternionLinearInterpolant, + interpolate_: function interpolate_(i1, t0, t, t1) { + var result = this.resultBuffer, + values = this.sampleValues, + stride = this.valueSize, + alpha = (t - t0) / (t1 - t0); + var offset = i1 * stride; - if ( material === undefined ) { + for (var end = offset + stride; offset !== end; offset += 4) { + Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha); + } - console.error( 'THREE.ObjectLoader: Undefined material ' + data.material ); + return result; + } + }); - } + /** + * A Track of quaternion keyframe values. + */ - object = new THREE.Sprite( material ); + function QuaternionKeyframeTrack(name, times, values, interpolation) { + KeyframeTrack.call(this, name, times, values, interpolation); + } - break; + QuaternionKeyframeTrack.prototype = Object.assign(Object.create(KeyframeTrack.prototype), { + constructor: QuaternionKeyframeTrack, + ValueTypeName: 'quaternion', + // ValueBufferType is inherited + DefaultInterpolation: InterpolateLinear, + InterpolantFactoryMethodLinear: function InterpolantFactoryMethodLinear(result) { + return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result); + }, + InterpolantFactoryMethodSmooth: undefined // not yet implemented - default: + }); - object = new THREE.Object3D(); + /** + * A Track that interpolates Strings + */ - } + function StringKeyframeTrack(name, times, values, interpolation) { + KeyframeTrack.call(this, name, times, values, interpolation); + } - object.uuid = data.uuid; + StringKeyframeTrack.prototype = Object.assign(Object.create(KeyframeTrack.prototype), { + constructor: StringKeyframeTrack, + ValueTypeName: 'string', + ValueBufferType: Array, + DefaultInterpolation: InterpolateDiscrete, + InterpolantFactoryMethodLinear: undefined, + InterpolantFactoryMethodSmooth: undefined + }); - if ( data.name !== undefined ) object.name = data.name; - if ( data.matrix !== undefined ) { + /** + * A Track of vectored keyframe values. + */ - matrix.fromArray( data.matrix ); - matrix.decompose( object.position, object.quaternion, object.scale ); + function VectorKeyframeTrack(name, times, values, interpolation) { + KeyframeTrack.call(this, name, times, values, interpolation); + } - } else { + VectorKeyframeTrack.prototype = Object.assign(Object.create(KeyframeTrack.prototype), { + constructor: VectorKeyframeTrack, + ValueTypeName: 'vector' // ValueBufferType is inherited + // DefaultInterpolation is inherited - if ( data.position !== undefined ) object.position.fromArray( data.position ); - if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation ); - if ( data.scale !== undefined ) object.scale.fromArray( data.scale ); + }); - } + function AnimationClip(name, duration, tracks, blendMode) { + this.name = name; + this.tracks = tracks; + this.duration = duration !== undefined ? duration : -1; + this.blendMode = blendMode !== undefined ? blendMode : NormalAnimationBlendMode; + this.uuid = MathUtils.generateUUID(); // this means it should figure out its duration by scanning the tracks - if ( data.visible !== undefined ) object.visible = data.visible; - if ( data.userData !== undefined ) object.userData = data.userData; + if (this.duration < 0) { + this.resetDuration(); + } + } - if ( data.children !== undefined ) { + function getTrackTypeForValueTypeName(typeName) { + switch (typeName.toLowerCase()) { + case 'scalar': + case 'double': + case 'float': + case 'number': + case 'integer': + return NumberKeyframeTrack; - for ( var child in data.children ) { + case 'vector': + case 'vector2': + case 'vector3': + case 'vector4': + return VectorKeyframeTrack; - object.add( this.parseObject( data.children[ child ], geometries, materials ) ); + case 'color': + return ColorKeyframeTrack; - } - - } + case 'quaternion': + return QuaternionKeyframeTrack; - return object; + case 'bool': + case 'boolean': + return BooleanKeyframeTrack; + case 'string': + return StringKeyframeTrack; } - }() - -}; + throw new Error('THREE.KeyframeTrack: Unsupported typeName: ' + typeName); + } -/** - * @author alteredq / http://alteredqualia.com/ - */ + function parseKeyframeTrack(json) { + if (json.type === undefined) { + throw new Error('THREE.KeyframeTrack: track type undefined, can not parse'); + } -THREE.SceneLoader = function () { + var trackType = getTrackTypeForValueTypeName(json.type); - this.onLoadStart = function () {}; - this.onLoadProgress = function() {}; - this.onLoadComplete = function () {}; + if (json.times === undefined) { + var times = [], + values = []; + AnimationUtils.flattenJSON(json.keys, times, values, 'value'); + json.times = times; + json.values = values; + } // derived classes can define a static parse method - this.callbackSync = function () {}; - this.callbackProgress = function () {}; - this.geometryHandlers = {}; - this.hierarchyHandlers = {}; + if (trackType.parse !== undefined) { + return trackType.parse(json); + } else { + // by default, we assume a constructor compatible with the base + return new trackType(json.name, json.times, json.values, json.interpolation); + } + } - this.addGeometryHandler( "ascii", THREE.JSONLoader ); + Object.assign(AnimationClip, { + parse: function parse(json) { + var tracks = [], + jsonTracks = json.tracks, + frameTime = 1.0 / (json.fps || 1.0); -}; + for (var i = 0, n = jsonTracks.length; i !== n; ++i) { + tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime)); + } -THREE.SceneLoader.prototype = { + return new AnimationClip(json.name, json.duration, tracks, json.blendMode); + }, + toJSON: function toJSON(clip) { + var tracks = [], + clipTracks = clip.tracks; + var json = { + 'name': clip.name, + 'duration': clip.duration, + 'tracks': tracks, + 'uuid': clip.uuid, + 'blendMode': clip.blendMode + }; - constructor: THREE.SceneLoader, + for (var i = 0, n = clipTracks.length; i !== n; ++i) { + tracks.push(KeyframeTrack.toJSON(clipTracks[i])); + } - load: function ( url, onLoad, onProgress, onError ) { + return json; + }, + CreateFromMorphTargetSequence: function CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) { + var numMorphTargets = morphTargetSequence.length; + var tracks = []; + + for (var i = 0; i < numMorphTargets; i++) { + var times = []; + var values = []; + times.push((i + numMorphTargets - 1) % numMorphTargets, i, (i + 1) % numMorphTargets); + values.push(0, 1, 0); + var order = AnimationUtils.getKeyframeOrder(times); + times = AnimationUtils.sortedArray(times, 1, order); + values = AnimationUtils.sortedArray(values, 1, order); // if there is a key at the first frame, duplicate it as the + // last frame as well for perfect loop. + + if (!noLoop && times[0] === 0) { + times.push(numMorphTargets); + values.push(values[0]); + } - var scope = this; + tracks.push(new NumberKeyframeTrack('.morphTargetInfluences[' + morphTargetSequence[i].name + ']', times, values).scale(1.0 / fps)); + } - var loader = new THREE.XHRLoader( scope.manager ); - loader.setCrossOrigin( this.crossOrigin ); - loader.load( url, function ( text ) { + return new AnimationClip(name, -1, tracks); + }, + findByName: function findByName(objectOrClipArray, name) { + var clipArray = objectOrClipArray; - scope.parse( JSON.parse( text ), onLoad, url ); + if (!Array.isArray(objectOrClipArray)) { + var o = objectOrClipArray; + clipArray = o.geometry && o.geometry.animations || o.animations; + } - } ); + for (var i = 0; i < clipArray.length; i++) { + if (clipArray[i].name === name) { + return clipArray[i]; + } + } - }, + return null; + }, + CreateClipsFromMorphTargetSequences: function CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) { + var animationToMorphTargets = {}; // tested with https://regex101.com/ on trick sequences + // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 - setCrossOrigin: function ( value ) { + var pattern = /^([\w-]*?)([\d]+)$/; // sort morph target names into animation groups based + // patterns like Walk_001, Walk_002, Run_001, Run_002 - this.crossOrigin = value; + for (var i = 0, il = morphTargets.length; i < il; i++) { + var morphTarget = morphTargets[i]; + var parts = morphTarget.name.match(pattern); - }, + if (parts && parts.length > 1) { + var name = parts[1]; + var animationMorphTargets = animationToMorphTargets[name]; - addGeometryHandler: function ( typeID, loaderClass ) { + if (!animationMorphTargets) { + animationToMorphTargets[name] = animationMorphTargets = []; + } - this.geometryHandlers[ typeID ] = { "loaderClass": loaderClass }; + animationMorphTargets.push(morphTarget); + } + } - }, + var clips = []; - addHierarchyHandler: function ( typeID, loaderClass ) { + for (var _name in animationToMorphTargets) { + clips.push(AnimationClip.CreateFromMorphTargetSequence(_name, animationToMorphTargets[_name], fps, noLoop)); + } - this.hierarchyHandlers[ typeID ] = { "loaderClass": loaderClass }; + return clips; + }, + // parse the animation.hierarchy format + parseAnimation: function parseAnimation(animation, bones) { + if (!animation) { + console.error('THREE.AnimationClip: No animation in JSONLoader data.'); + return null; + } - }, + var addNonemptyTrack = function addNonemptyTrack(trackType, trackName, animationKeys, propertyName, destTracks) { + // only return track if there are actually keys. + if (animationKeys.length !== 0) { + var times = []; + var values = []; + AnimationUtils.flattenJSON(animationKeys, times, values, propertyName); // empty keys are filtered out, so check again - parse: function ( json, callbackFinished, url ) { + if (times.length !== 0) { + destTracks.push(new trackType(trackName, times, values)); + } + } + }; - var scope = this; + var tracks = []; + var clipName = animation.name || 'default'; + var fps = animation.fps || 30; + var blendMode = animation.blendMode; // automatic length determination in AnimationClip. - var urlBase = THREE.Loader.prototype.extractUrlBase( url ); + var duration = animation.length || -1; + var hierarchyTracks = animation.hierarchy || []; - var geometry, material, camera, fog, - texture, images, color, - light, hex, intensity, - counter_models, counter_textures, - total_models, total_textures, - result; + for (var h = 0; h < hierarchyTracks.length; h++) { + var animationKeys = hierarchyTracks[h].keys; // skip empty tracks - var target_array = []; + if (!animationKeys || animationKeys.length === 0) continue; // process morph targets - var data = json; + if (animationKeys[0].morphTargets) { + // figure out all morph targets used in this track + var morphTargetNames = {}; + var k = void 0; - // async geometry loaders + for (k = 0; k < animationKeys.length; k++) { + if (animationKeys[k].morphTargets) { + for (var m = 0; m < animationKeys[k].morphTargets.length; m++) { + morphTargetNames[animationKeys[k].morphTargets[m]] = -1; + } + } + } // create a track for each morph target with all zero + // morphTargetInfluences except for the keys in which + // the morphTarget is named. - for ( var typeID in this.geometryHandlers ) { - var loaderClass = this.geometryHandlers[ typeID ][ "loaderClass" ]; - this.geometryHandlers[ typeID ][ "loaderObject" ] = new loaderClass(); + for (var morphTargetName in morphTargetNames) { + var times = []; + var values = []; - } + for (var _m = 0; _m !== animationKeys[k].morphTargets.length; ++_m) { + var animationKey = animationKeys[k]; + times.push(animationKey.time); + values.push(animationKey.morphTarget === morphTargetName ? 1 : 0); + } - // async hierachy loaders + tracks.push(new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values)); + } - for ( var typeID in this.hierarchyHandlers ) { + duration = morphTargetNames.length * (fps || 1.0); + } else { + // ...assume skeletal animation + var boneName = '.bones[' + bones[h].name + ']'; + addNonemptyTrack(VectorKeyframeTrack, boneName + '.position', animationKeys, 'pos', tracks); + addNonemptyTrack(QuaternionKeyframeTrack, boneName + '.quaternion', animationKeys, 'rot', tracks); + addNonemptyTrack(VectorKeyframeTrack, boneName + '.scale', animationKeys, 'scl', tracks); + } + } - var loaderClass = this.hierarchyHandlers[ typeID ][ "loaderClass" ]; - this.hierarchyHandlers[ typeID ][ "loaderObject" ] = new loaderClass(); + if (tracks.length === 0) { + return null; + } + var clip = new AnimationClip(clipName, duration, tracks, blendMode); + return clip; } + }); + Object.assign(AnimationClip.prototype, { + resetDuration: function resetDuration() { + var tracks = this.tracks; + var duration = 0; - counter_models = 0; - counter_textures = 0; - - result = { - - scene: new THREE.Scene(), - geometries: {}, - face_materials: {}, - materials: {}, - textures: {}, - objects: {}, - cameras: {}, - lights: {}, - fogs: {}, - empties: {}, - groups: {} - - }; - - if ( data.transform ) { - - var position = data.transform.position, - rotation = data.transform.rotation, - scale = data.transform.scale; - - if ( position ) { - - result.scene.position.fromArray( position ); - + for (var i = 0, n = tracks.length; i !== n; ++i) { + var track = this.tracks[i]; + duration = Math.max(duration, track.times[track.times.length - 1]); } - if ( rotation ) { - - result.scene.rotation.fromArray( rotation ); - + this.duration = duration; + return this; + }, + trim: function trim() { + for (var i = 0; i < this.tracks.length; i++) { + this.tracks[i].trim(0, this.duration); } - if ( scale ) { - - result.scene.scale.fromArray( scale ); + return this; + }, + validate: function validate() { + var valid = true; + for (var i = 0; i < this.tracks.length; i++) { + valid = valid && this.tracks[i].validate(); } - if ( position || rotation || scale ) { + return valid; + }, + optimize: function optimize() { + for (var i = 0; i < this.tracks.length; i++) { + this.tracks[i].optimize(); + } - result.scene.updateMatrix(); - result.scene.updateMatrixWorld(); + return this; + }, + clone: function clone() { + var tracks = []; + for (var i = 0; i < this.tracks.length; i++) { + tracks.push(this.tracks[i].clone()); } + return new AnimationClip(this.name, this.duration, tracks, this.blendMode); } + }); - function get_url( source_url, url_type ) { - - if ( url_type == "relativeToHTML" ) { + var Cache = { + enabled: false, + files: {}, + add: function add(key, file) { + if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Adding key:', key ); - return source_url; - - } else { + this.files[key] = file; + }, + get: function get(key) { + if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Checking key:', key ); - return urlBase + source_url; + return this.files[key]; + }, + remove: function remove(key) { + delete this.files[key]; + }, + clear: function clear() { + this.files = {}; + } + }; + function LoadingManager(onLoad, onProgress, onError) { + var scope = this; + var isLoading = false; + var itemsLoaded = 0; + var itemsTotal = 0; + var urlModifier = undefined; + var handlers = []; // Refer to #5689 for the reason why we don't set .onStart + // in the constructor + + this.onStart = undefined; + this.onLoad = onLoad; + this.onProgress = onProgress; + this.onError = onError; + + this.itemStart = function (url) { + itemsTotal++; + + if (isLoading === false) { + if (scope.onStart !== undefined) { + scope.onStart(url, itemsLoaded, itemsTotal); + } } + isLoading = true; }; - // toplevel loader function, delegates to handle_children + this.itemEnd = function (url) { + itemsLoaded++; - function handle_objects() { + if (scope.onProgress !== undefined) { + scope.onProgress(url, itemsLoaded, itemsTotal); + } - handle_children( result.scene, data.objects ); + if (itemsLoaded === itemsTotal) { + isLoading = false; - } + if (scope.onLoad !== undefined) { + scope.onLoad(); + } + } + }; - // handle all the children from the loaded json and attach them to given parent + this.itemError = function (url) { + if (scope.onError !== undefined) { + scope.onError(url); + } + }; - function handle_children( parent, children ) { + this.resolveURL = function (url) { + if (urlModifier) { + return urlModifier(url); + } - var mat, dst, pos, rot, scl, quat; + return url; + }; - for ( var objID in children ) { + this.setURLModifier = function (transform) { + urlModifier = transform; + return this; + }; - // check by id if child has already been handled, - // if not, create new object + this.addHandler = function (regex, loader) { + handlers.push(regex, loader); + return this; + }; - var object = result.objects[ objID ]; - var objJSON = children[ objID ]; + this.removeHandler = function (regex) { + var index = handlers.indexOf(regex); - if ( object === undefined ) { + if (index !== -1) { + handlers.splice(index, 2); + } - // meshes + return this; + }; - if ( objJSON.type && ( objJSON.type in scope.hierarchyHandlers ) ) { + this.getHandler = function (file) { + for (var i = 0, l = handlers.length; i < l; i += 2) { + var regex = handlers[i]; + var loader = handlers[i + 1]; + if (regex.global) regex.lastIndex = 0; // see #17920 - if ( objJSON.loading === undefined ) { + if (regex.test(file)) { + return loader; + } + } - var reservedTypes = { - "type": 1, "url": 1, "material": 1, - "position": 1, "rotation": 1, "scale" : 1, - "visible": 1, "children": 1, "userData": 1, - "skin": 1, "morph": 1, "mirroredLoop": 1, "duration": 1 - }; + return null; + }; + } - var loaderParameters = {}; + var DefaultLoadingManager = new LoadingManager(); - for ( var parType in objJSON ) { + function Loader(manager) { + this.manager = manager !== undefined ? manager : DefaultLoadingManager; + this.crossOrigin = 'anonymous'; + this.withCredentials = false; + this.path = ''; + this.resourcePath = ''; + this.requestHeader = {}; + } - if ( ! ( parType in reservedTypes ) ) { + Object.assign(Loader.prototype, { + load: function load() + /* url, onLoad, onProgress, onError */ + {}, + loadAsync: function loadAsync(url, onProgress) { + var scope = this; + return new Promise(function (resolve, reject) { + scope.load(url, resolve, onProgress, reject); + }); + }, + parse: function parse() + /* data */ + {}, + setCrossOrigin: function setCrossOrigin(crossOrigin) { + this.crossOrigin = crossOrigin; + return this; + }, + setWithCredentials: function setWithCredentials(value) { + this.withCredentials = value; + return this; + }, + setPath: function setPath(path) { + this.path = path; + return this; + }, + setResourcePath: function setResourcePath(resourcePath) { + this.resourcePath = resourcePath; + return this; + }, + setRequestHeader: function setRequestHeader(requestHeader) { + this.requestHeader = requestHeader; + return this; + } + }); - loaderParameters[ parType ] = objJSON[ parType ]; + var loading = {}; - } + function FileLoader(manager) { + Loader.call(this, manager); + } + FileLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: FileLoader, + load: function load(url, onLoad, onProgress, onError) { + if (url === undefined) url = ''; + if (this.path !== undefined) url = this.path + url; + url = this.manager.resolveURL(url); + var scope = this; + var cached = Cache.get(url); + + if (cached !== undefined) { + scope.manager.itemStart(url); + setTimeout(function () { + if (onLoad) onLoad(cached); + scope.manager.itemEnd(url); + }, 0); + return cached; + } // Check if request is duplicate + + + if (loading[url] !== undefined) { + loading[url].push({ + onLoad: onLoad, + onProgress: onProgress, + onError: onError + }); + return; + } // Check for data: URI + + + var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; + var dataUriRegexResult = url.match(dataUriRegex); + var request; // Safari can not handle Data URIs through XMLHttpRequest so process manually + + if (dataUriRegexResult) { + var mimeType = dataUriRegexResult[1]; + var isBase64 = !!dataUriRegexResult[2]; + var data = dataUriRegexResult[3]; + data = decodeURIComponent(data); + if (isBase64) data = atob(data); + + try { + var response; + var responseType = (this.responseType || '').toLowerCase(); + + switch (responseType) { + case 'arraybuffer': + case 'blob': + var view = new Uint8Array(data.length); + + for (var i = 0; i < data.length; i++) { + view[i] = data.charCodeAt(i); } - material = result.materials[ objJSON.material ]; - - objJSON.loading = true; - - var loader = scope.hierarchyHandlers[ objJSON.type ][ "loaderObject" ]; - - // ColladaLoader - - if ( loader.options ) { - - loader.load( get_url( objJSON.url, data.urlBaseType ), create_callback_hierachy( objID, parent, material, objJSON ) ); + if (responseType === 'blob') { + response = new Blob([view.buffer], { + type: mimeType + }); + } else { + response = view.buffer; + } - // UTF8Loader - // OBJLoader + break; - } else { + case 'document': + var parser = new DOMParser(); + response = parser.parseFromString(data, mimeType); + break; - loader.load( get_url( objJSON.url, data.urlBaseType ), create_callback_hierachy( objID, parent, material, objJSON ), loaderParameters ); + case 'json': + response = JSON.parse(data); + break; - } + default: + // 'text' or other + response = data; + break; + } // Wait for next browser tick like standard XMLHttpRequest event dispatching does + + + setTimeout(function () { + if (onLoad) onLoad(response); + scope.manager.itemEnd(url); + }, 0); + } catch (error) { + // Wait for next browser tick like standard XMLHttpRequest event dispatching does + setTimeout(function () { + if (onError) onError(error); + scope.manager.itemError(url); + scope.manager.itemEnd(url); + }, 0); + } + } else { + // Initialise array for duplicate requests + loading[url] = []; + loading[url].push({ + onLoad: onLoad, + onProgress: onProgress, + onError: onError + }); + request = new XMLHttpRequest(); + request.open('GET', url, true); + request.addEventListener('load', function (event) { + var response = this.response; + var callbacks = loading[url]; + delete loading[url]; + + if (this.status === 200 || this.status === 0) { + // Some browsers return HTTP Status 0 when using non-http protocol + // e.g. 'file://' or 'data://'. Handle as success. + if (this.status === 0) console.warn('THREE.FileLoader: HTTP Status 0 received.'); // Add to cache only on HTTP success, so that we do not cache + // error response bodies as proper responses to requests. + + Cache.add(url, response); + + for (var _i = 0, il = callbacks.length; _i < il; _i++) { + var callback = callbacks[_i]; + if (callback.onLoad) callback.onLoad(response); + } + scope.manager.itemEnd(url); + } else { + for (var _i2 = 0, _il = callbacks.length; _i2 < _il; _i2++) { + var _callback = callbacks[_i2]; + if (_callback.onError) _callback.onError(event); } - } else if ( objJSON.geometry !== undefined ) { + scope.manager.itemError(url); + scope.manager.itemEnd(url); + } + }, false); + request.addEventListener('progress', function (event) { + var callbacks = loading[url]; - geometry = result.geometries[ objJSON.geometry ]; + for (var _i3 = 0, il = callbacks.length; _i3 < il; _i3++) { + var callback = callbacks[_i3]; + if (callback.onProgress) callback.onProgress(event); + } + }, false); + request.addEventListener('error', function (event) { + var callbacks = loading[url]; + delete loading[url]; + + for (var _i4 = 0, il = callbacks.length; _i4 < il; _i4++) { + var callback = callbacks[_i4]; + if (callback.onError) callback.onError(event); + } - // geometry already loaded + scope.manager.itemError(url); + scope.manager.itemEnd(url); + }, false); + request.addEventListener('abort', function (event) { + var callbacks = loading[url]; + delete loading[url]; - if ( geometry ) { + for (var _i5 = 0, il = callbacks.length; _i5 < il; _i5++) { + var callback = callbacks[_i5]; + if (callback.onError) callback.onError(event); + } - var needsTangents = false; + scope.manager.itemError(url); + scope.manager.itemEnd(url); + }, false); + if (this.responseType !== undefined) request.responseType = this.responseType; + if (this.withCredentials !== undefined) request.withCredentials = this.withCredentials; + if (request.overrideMimeType) request.overrideMimeType(this.mimeType !== undefined ? this.mimeType : 'text/plain'); - material = result.materials[ objJSON.material ]; - needsTangents = material instanceof THREE.ShaderMaterial; + for (var header in this.requestHeader) { + request.setRequestHeader(header, this.requestHeader[header]); + } - pos = objJSON.position; - rot = objJSON.rotation; - scl = objJSON.scale; - mat = objJSON.matrix; - quat = objJSON.quaternion; + request.send(null); + } - // use materials from the model file - // if there is no material specified in the object + scope.manager.itemStart(url); + return request; + }, + setResponseType: function setResponseType(value) { + this.responseType = value; + return this; + }, + setMimeType: function setMimeType(value) { + this.mimeType = value; + return this; + } + }); - if ( ! objJSON.material ) { + function AnimationLoader(manager) { + Loader.call(this, manager); + } - material = new THREE.MeshFaceMaterial( result.face_materials[ objJSON.geometry ] ); + AnimationLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: AnimationLoader, + load: function load(url, onLoad, onProgress, onError) { + var scope = this; + var loader = new FileLoader(scope.manager); + loader.setPath(scope.path); + loader.setRequestHeader(scope.requestHeader); + loader.setWithCredentials(scope.withCredentials); + loader.load(url, function (text) { + try { + onLoad(scope.parse(JSON.parse(text))); + } catch (e) { + if (onError) { + onError(e); + } else { + console.error(e); + } - } + scope.manager.itemError(url); + } + }, onProgress, onError); + }, + parse: function parse(json) { + var animations = []; - // use materials from the model file - // if there is just empty face material - // (must create new material as each model has its own face material) + for (var i = 0; i < json.length; i++) { + var clip = AnimationClip.parse(json[i]); + animations.push(clip); + } - if ( ( material instanceof THREE.MeshFaceMaterial ) && material.materials.length === 0 ) { + return animations; + } + }); - material = new THREE.MeshFaceMaterial( result.face_materials[ objJSON.geometry ] ); + /** + * Abstract Base class to block based textures loader (dds, pvr, ...) + * + * Sub classes have to implement the parse() method which will be used in load(). + */ - } + function CompressedTextureLoader(manager) { + Loader.call(this, manager); + } - if ( material instanceof THREE.MeshFaceMaterial ) { + CompressedTextureLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: CompressedTextureLoader, + load: function load(url, onLoad, onProgress, onError) { + var scope = this; + var images = []; + var texture = new CompressedTexture(); + texture.image = images; + var loader = new FileLoader(this.manager); + loader.setPath(this.path); + loader.setResponseType('arraybuffer'); + loader.setRequestHeader(this.requestHeader); + loader.setWithCredentials(scope.withCredentials); + var loaded = 0; + + function loadTexture(i) { + loader.load(url[i], function (buffer) { + var texDatas = scope.parse(buffer, true); + images[i] = { + width: texDatas.width, + height: texDatas.height, + format: texDatas.format, + mipmaps: texDatas.mipmaps + }; + loaded += 1; + + if (loaded === 6) { + if (texDatas.mipmapCount === 1) texture.minFilter = LinearFilter; + texture.format = texDatas.format; + texture.needsUpdate = true; + if (onLoad) onLoad(texture); + } + }, onProgress, onError); + } - for ( var i = 0; i < material.materials.length; i ++ ) { + if (Array.isArray(url)) { + for (var i = 0, il = url.length; i < il; ++i) { + loadTexture(i); + } + } else { + // compressed cubemap texture stored in a single DDS file + loader.load(url, function (buffer) { + var texDatas = scope.parse(buffer, true); - needsTangents = needsTangents || ( material.materials[ i ] instanceof THREE.ShaderMaterial ); + if (texDatas.isCubemap) { + var faces = texDatas.mipmaps.length / texDatas.mipmapCount; - } + for (var f = 0; f < faces; f++) { + images[f] = { + mipmaps: [] + }; + for (var _i = 0; _i < texDatas.mipmapCount; _i++) { + images[f].mipmaps.push(texDatas.mipmaps[f * texDatas.mipmapCount + _i]); + images[f].format = texDatas.format; + images[f].width = texDatas.width; + images[f].height = texDatas.height; } + } + } else { + texture.image.width = texDatas.width; + texture.image.height = texDatas.height; + texture.mipmaps = texDatas.mipmaps; + } - if ( needsTangents ) { - - geometry.computeTangents(); - - } + if (texDatas.mipmapCount === 1) { + texture.minFilter = LinearFilter; + } - if ( objJSON.skin ) { + texture.format = texDatas.format; + texture.needsUpdate = true; + if (onLoad) onLoad(texture); + }, onProgress, onError); + } - object = new THREE.SkinnedMesh( geometry, material ); + return texture; + } + }); - } else if ( objJSON.morph ) { + function ImageLoader(manager) { + Loader.call(this, manager); + } - object = new THREE.MorphAnimMesh( geometry, material ); + ImageLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: ImageLoader, + load: function load(url, onLoad, onProgress, onError) { + if (this.path !== undefined) url = this.path + url; + url = this.manager.resolveURL(url); + var scope = this; + var cached = Cache.get(url); - if ( objJSON.duration !== undefined ) { + if (cached !== undefined) { + scope.manager.itemStart(url); + setTimeout(function () { + if (onLoad) onLoad(cached); + scope.manager.itemEnd(url); + }, 0); + return cached; + } - object.duration = objJSON.duration; + var image = document.createElementNS('http://www.w3.org/1999/xhtml', 'img'); - } + function onImageLoad() { + image.removeEventListener('load', onImageLoad, false); + image.removeEventListener('error', onImageError, false); + Cache.add(url, this); + if (onLoad) onLoad(this); + scope.manager.itemEnd(url); + } - if ( objJSON.time !== undefined ) { + function onImageError(event) { + image.removeEventListener('load', onImageLoad, false); + image.removeEventListener('error', onImageError, false); + if (onError) onError(event); + scope.manager.itemError(url); + scope.manager.itemEnd(url); + } - object.time = objJSON.time; + image.addEventListener('load', onImageLoad, false); + image.addEventListener('error', onImageError, false); - } + if (url.substr(0, 5) !== 'data:') { + if (this.crossOrigin !== undefined) image.crossOrigin = this.crossOrigin; + } - if ( objJSON.mirroredLoop !== undefined ) { + scope.manager.itemStart(url); + image.src = url; + return image; + } + }); - object.mirroredLoop = objJSON.mirroredLoop; + function CubeTextureLoader(manager) { + Loader.call(this, manager); + } - } + CubeTextureLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: CubeTextureLoader, + load: function load(urls, onLoad, onProgress, onError) { + var texture = new CubeTexture(); + var loader = new ImageLoader(this.manager); + loader.setCrossOrigin(this.crossOrigin); + loader.setPath(this.path); + var loaded = 0; - if ( material.morphNormals ) { + function loadTexture(i) { + loader.load(urls[i], function (image) { + texture.images[i] = image; + loaded++; - geometry.computeMorphNormals(); + if (loaded === 6) { + texture.needsUpdate = true; + if (onLoad) onLoad(texture); + } + }, undefined, onError); + } - } + for (var i = 0; i < urls.length; ++i) { + loadTexture(i); + } - } else { + return texture; + } + }); - object = new THREE.Mesh( geometry, material ); + /** + * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) + * + * Sub classes have to implement the parse() method which will be used in load(). + */ - } + function DataTextureLoader(manager) { + Loader.call(this, manager); + } - object.name = objID; + DataTextureLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: DataTextureLoader, + load: function load(url, onLoad, onProgress, onError) { + var scope = this; + var texture = new DataTexture(); + var loader = new FileLoader(this.manager); + loader.setResponseType('arraybuffer'); + loader.setRequestHeader(this.requestHeader); + loader.setPath(this.path); + loader.setWithCredentials(scope.withCredentials); + loader.load(url, function (buffer) { + var texData = scope.parse(buffer); + if (!texData) return; + + if (texData.image !== undefined) { + texture.image = texData.image; + } else if (texData.data !== undefined) { + texture.image.width = texData.width; + texture.image.height = texData.height; + texture.image.data = texData.data; + } - if ( mat ) { + texture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping; + texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping; + texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter; + texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter; + texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1; - object.matrixAutoUpdate = false; - object.matrix.set( - mat[0], mat[1], mat[2], mat[3], - mat[4], mat[5], mat[6], mat[7], - mat[8], mat[9], mat[10], mat[11], - mat[12], mat[13], mat[14], mat[15] - ); + if (texData.format !== undefined) { + texture.format = texData.format; + } - } else { + if (texData.type !== undefined) { + texture.type = texData.type; + } - object.position.fromArray( pos ); + if (texData.mipmaps !== undefined) { + texture.mipmaps = texData.mipmaps; + texture.minFilter = LinearMipmapLinearFilter; // presumably... + } - if ( quat ) { + if (texData.mipmapCount === 1) { + texture.minFilter = LinearFilter; + } - object.quaternion.fromArray( quat ); + texture.needsUpdate = true; + if (onLoad) onLoad(texture, texData); + }, onProgress, onError); + return texture; + } + }); - } else { + function TextureLoader(manager) { + Loader.call(this, manager); + } - object.rotation.fromArray( rot ); + TextureLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: TextureLoader, + load: function load(url, onLoad, onProgress, onError) { + var texture = new Texture(); + var loader = new ImageLoader(this.manager); + loader.setCrossOrigin(this.crossOrigin); + loader.setPath(this.path); + loader.load(url, function (image) { + texture.image = image; // JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB. - } + var isJPEG = url.search(/\.jpe?g($|\?)/i) > 0 || url.search(/^data\:image\/jpeg/) === 0; + texture.format = isJPEG ? RGBFormat : RGBAFormat; + texture.needsUpdate = true; - object.scale.fromArray( scl ); + if (onLoad !== undefined) { + onLoad(texture); + } + }, onProgress, onError); + return texture; + } + }); - } + /** + * Extensible curve object. + * + * Some common of curve methods: + * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget ) + * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget ) + * .getPoints(), .getSpacedPoints() + * .getLength() + * .updateArcLengths() + * + * This following curves inherit from THREE.Curve: + * + * -- 2D curves -- + * THREE.ArcCurve + * THREE.CubicBezierCurve + * THREE.EllipseCurve + * THREE.LineCurve + * THREE.QuadraticBezierCurve + * THREE.SplineCurve + * + * -- 3D curves -- + * THREE.CatmullRomCurve3 + * THREE.CubicBezierCurve3 + * THREE.LineCurve3 + * THREE.QuadraticBezierCurve3 + * + * A series of curves can be represented as a THREE.CurvePath. + * + **/ - object.visible = objJSON.visible; - object.castShadow = objJSON.castShadow; - object.receiveShadow = objJSON.receiveShadow; + function Curve() { + this.type = 'Curve'; + this.arcLengthDivisions = 200; + } - parent.add( object ); + Object.assign(Curve.prototype, { + // Virtual base class method to overwrite and implement in subclasses + // - t [0 .. 1] + getPoint: function getPoint() + /* t, optionalTarget */ + { + console.warn('THREE.Curve: .getPoint() not implemented.'); + return null; + }, + // Get point at relative position in curve according to arc length + // - u [0 .. 1] + getPointAt: function getPointAt(u, optionalTarget) { + var t = this.getUtoTmapping(u); + return this.getPoint(t, optionalTarget); + }, + // Get sequence of points using getPoint( t ) + getPoints: function getPoints(divisions) { + if (divisions === undefined) divisions = 5; + var points = []; - result.objects[ objID ] = object; + for (var d = 0; d <= divisions; d++) { + points.push(this.getPoint(d / divisions)); + } - } + return points; + }, + // Get sequence of points using getPointAt( u ) + getSpacedPoints: function getSpacedPoints(divisions) { + if (divisions === undefined) divisions = 5; + var points = []; - // lights + for (var d = 0; d <= divisions; d++) { + points.push(this.getPointAt(d / divisions)); + } - } else if ( objJSON.type === "AmbientLight" || objJSON.type === "PointLight" || - objJSON.type === "DirectionalLight" || objJSON.type === "SpotLight" || - objJSON.type === "HemisphereLight" || objJSON.type === "AreaLight" ) { + return points; + }, + // Get total curve arc length + getLength: function getLength() { + var lengths = this.getLengths(); + return lengths[lengths.length - 1]; + }, + // Get list of cumulative segment lengths + getLengths: function getLengths(divisions) { + if (divisions === undefined) divisions = this.arcLengthDivisions; - var color = objJSON.color; - var intensity = objJSON.intensity; - var distance = objJSON.distance; - var position = objJSON.position; - var rotation = objJSON.rotation; + if (this.cacheArcLengths && this.cacheArcLengths.length === divisions + 1 && !this.needsUpdate) { + return this.cacheArcLengths; + } - switch ( objJSON.type ) { + this.needsUpdate = false; + var cache = []; + var current, + last = this.getPoint(0); + var sum = 0; + cache.push(0); - case 'AmbientLight': - light = new THREE.AmbientLight( color ); - break; + for (var p = 1; p <= divisions; p++) { + current = this.getPoint(p / divisions); + sum += current.distanceTo(last); + cache.push(sum); + last = current; + } - case 'PointLight': - light = new THREE.PointLight( color, intensity, distance ); - light.position.fromArray( position ); - break; + this.cacheArcLengths = cache; + return cache; // { sums: cache, sum: sum }; Sum is in the last element. + }, + updateArcLengths: function updateArcLengths() { + this.needsUpdate = true; + this.getLengths(); + }, + // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant + getUtoTmapping: function getUtoTmapping(u, distance) { + var arcLengths = this.getLengths(); + var i = 0; + var il = arcLengths.length; + var targetArcLength; // The targeted u distance value to get + + if (distance) { + targetArcLength = distance; + } else { + targetArcLength = u * arcLengths[il - 1]; + } // binary search for the index with largest value smaller than target u distance - case 'DirectionalLight': - light = new THREE.DirectionalLight( color, intensity ); - light.position.fromArray( objJSON.direction ); - break; - case 'SpotLight': - light = new THREE.SpotLight( color, intensity, distance, 1 ); - light.angle = objJSON.angle; - light.position.fromArray( position ); - light.target.set( position[ 0 ], position[ 1 ] - distance, position[ 2 ] ); - light.target.applyEuler( new THREE.Euler( rotation[ 0 ], rotation[ 1 ], rotation[ 2 ], 'XYZ' ) ); - break; + var low = 0, + high = il - 1, + comparison; - case 'HemisphereLight': - light = new THREE.DirectionalLight( color, intensity, distance ); - light.target.set( position[ 0 ], position[ 1 ] - distance, position[ 2 ] ); - light.target.applyEuler( new THREE.Euler( rotation[ 0 ], rotation[ 1 ], rotation[ 2 ], 'XYZ' ) ); - break; + while (low <= high) { + i = Math.floor(low + (high - low) / 2); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats - case 'AreaLight': - light = new THREE.AreaLight(color, intensity); - light.position.fromArray( position ); - light.width = objJSON.size; - light.height = objJSON.size_y; - break; + comparison = arcLengths[i] - targetArcLength; - } + if (comparison < 0) { + low = i + 1; + } else if (comparison > 0) { + high = i - 1; + } else { + high = i; + break; // DONE + } + } - parent.add( light ); + i = high; - light.name = objID; - result.lights[ objID ] = light; - result.objects[ objID ] = light; + if (arcLengths[i] === targetArcLength) { + return i / (il - 1); + } // we could get finer grain at lengths, or use simple interpolation between two points - // cameras - } else if ( objJSON.type === "PerspectiveCamera" || objJSON.type === "OrthographicCamera" ) { + var lengthBefore = arcLengths[i]; + var lengthAfter = arcLengths[i + 1]; + var segmentLength = lengthAfter - lengthBefore; // determine where we are between the 'before' and 'after' points - pos = objJSON.position; - rot = objJSON.rotation; - quat = objJSON.quaternion; + var segmentFraction = (targetArcLength - lengthBefore) / segmentLength; // add that fractional amount to t - if ( objJSON.type === "PerspectiveCamera" ) { + var t = (i + segmentFraction) / (il - 1); + return t; + }, + // Returns a unit vector tangent at t + // In case any sub curve does not implement its tangent derivation, + // 2 points a small delta apart will be used to find its gradient + // which seems to give a reasonable approximation + getTangent: function getTangent(t, optionalTarget) { + var delta = 0.0001; + var t1 = t - delta; + var t2 = t + delta; // Capping in case of danger + + if (t1 < 0) t1 = 0; + if (t2 > 1) t2 = 1; + var pt1 = this.getPoint(t1); + var pt2 = this.getPoint(t2); + var tangent = optionalTarget || (pt1.isVector2 ? new Vector2() : new Vector3()); + tangent.copy(pt2).sub(pt1).normalize(); + return tangent; + }, + getTangentAt: function getTangentAt(u, optionalTarget) { + var t = this.getUtoTmapping(u); + return this.getTangent(t, optionalTarget); + }, + computeFrenetFrames: function computeFrenetFrames(segments, closed) { + // see http://www.cs.indiana.edu/pub/techreports/TR425.pdf + var normal = new Vector3(); + var tangents = []; + var normals = []; + var binormals = []; + var vec = new Vector3(); + var mat = new Matrix4(); // compute the tangent vectors for each segment on the curve - camera = new THREE.PerspectiveCamera( objJSON.fov, objJSON.aspect, objJSON.near, objJSON.far ); + for (var i = 0; i <= segments; i++) { + var u = i / segments; + tangents[i] = this.getTangentAt(u, new Vector3()); + tangents[i].normalize(); + } // select an initial normal vector perpendicular to the first tangent vector, + // and in the direction of the minimum tangent xyz component - } else if ( objJSON.type === "OrthographicCamera" ) { - camera = new THREE.OrthographicCamera( objJSON.left, objJSON.right, objJSON.top, objJSON.bottom, objJSON.near, objJSON.far ); + normals[0] = new Vector3(); + binormals[0] = new Vector3(); + var min = Number.MAX_VALUE; + var tx = Math.abs(tangents[0].x); + var ty = Math.abs(tangents[0].y); + var tz = Math.abs(tangents[0].z); - } + if (tx <= min) { + min = tx; + normal.set(1, 0, 0); + } - camera.name = objID; - camera.position.fromArray( pos ); + if (ty <= min) { + min = ty; + normal.set(0, 1, 0); + } - if ( quat !== undefined ) { + if (tz <= min) { + normal.set(0, 0, 1); + } - camera.quaternion.fromArray( quat ); + vec.crossVectors(tangents[0], normal).normalize(); + normals[0].crossVectors(tangents[0], vec); + binormals[0].crossVectors(tangents[0], normals[0]); // compute the slowly-varying normal and binormal vectors for each segment on the curve - } else if ( rot !== undefined ) { + for (var _i = 1; _i <= segments; _i++) { + normals[_i] = normals[_i - 1].clone(); + binormals[_i] = binormals[_i - 1].clone(); + vec.crossVectors(tangents[_i - 1], tangents[_i]); - camera.rotation.fromArray( rot ); + if (vec.length() > Number.EPSILON) { + vec.normalize(); + var theta = Math.acos(MathUtils.clamp(tangents[_i - 1].dot(tangents[_i]), -1, 1)); // clamp for floating pt errors - } + normals[_i].applyMatrix4(mat.makeRotationAxis(vec, theta)); + } - parent.add( camera ); + binormals[_i].crossVectors(tangents[_i], normals[_i]); + } // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same - result.cameras[ objID ] = camera; - result.objects[ objID ] = camera; - // pure Object3D + if (closed === true) { + var _theta = Math.acos(MathUtils.clamp(normals[0].dot(normals[segments]), -1, 1)); - } else { + _theta /= segments; - pos = objJSON.position; - rot = objJSON.rotation; - scl = objJSON.scale; - quat = objJSON.quaternion; + if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) { + _theta = -_theta; + } - object = new THREE.Object3D(); - object.name = objID; - object.position.fromArray( pos ); + for (var _i2 = 1; _i2 <= segments; _i2++) { + // twist a little... + normals[_i2].applyMatrix4(mat.makeRotationAxis(tangents[_i2], _theta * _i2)); - if ( quat ) { + binormals[_i2].crossVectors(tangents[_i2], normals[_i2]); + } + } - object.quaternion.fromArray( quat ); - - } else { - - object.rotation.fromArray( rot ); - - } - - object.scale.fromArray( scl ); - object.visible = ( objJSON.visible !== undefined ) ? objJSON.visible : false; - - parent.add( object ); - - result.objects[ objID ] = object; - result.empties[ objID ] = object; + return { + tangents: tangents, + normals: normals, + binormals: binormals + }; + }, + clone: function clone() { + return new this.constructor().copy(this); + }, + copy: function copy(source) { + this.arcLengthDivisions = source.arcLengthDivisions; + return this; + }, + toJSON: function toJSON() { + var data = { + metadata: { + version: 4.5, + type: 'Curve', + generator: 'Curve.toJSON' + } + }; + data.arcLengthDivisions = this.arcLengthDivisions; + data.type = this.type; + return data; + }, + fromJSON: function fromJSON(json) { + this.arcLengthDivisions = json.arcLengthDivisions; + return this; + } + }); - } + function EllipseCurve(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { + Curve.call(this); + this.type = 'EllipseCurve'; + this.aX = aX || 0; + this.aY = aY || 0; + this.xRadius = xRadius || 1; + this.yRadius = yRadius || 1; + this.aStartAngle = aStartAngle || 0; + this.aEndAngle = aEndAngle || 2 * Math.PI; + this.aClockwise = aClockwise || false; + this.aRotation = aRotation || 0; + } - if ( object ) { + EllipseCurve.prototype = Object.create(Curve.prototype); + EllipseCurve.prototype.constructor = EllipseCurve; + EllipseCurve.prototype.isEllipseCurve = true; - if ( objJSON.userData !== undefined ) { + EllipseCurve.prototype.getPoint = function (t, optionalTarget) { + var point = optionalTarget || new Vector2(); + var twoPi = Math.PI * 2; + var deltaAngle = this.aEndAngle - this.aStartAngle; + var samePoints = Math.abs(deltaAngle) < Number.EPSILON; // ensures that deltaAngle is 0 .. 2 PI - for ( var key in objJSON.userData ) { + while (deltaAngle < 0) { + deltaAngle += twoPi; + } - var value = objJSON.userData[ key ]; - object.userData[ key ] = value; + while (deltaAngle > twoPi) { + deltaAngle -= twoPi; + } - } + if (deltaAngle < Number.EPSILON) { + if (samePoints) { + deltaAngle = 0; + } else { + deltaAngle = twoPi; + } + } - } + if (this.aClockwise === true && !samePoints) { + if (deltaAngle === twoPi) { + deltaAngle = -twoPi; + } else { + deltaAngle = deltaAngle - twoPi; + } + } - if ( objJSON.groups !== undefined ) { + var angle = this.aStartAngle + t * deltaAngle; + var x = this.aX + this.xRadius * Math.cos(angle); + var y = this.aY + this.yRadius * Math.sin(angle); - for ( var i = 0; i < objJSON.groups.length; i ++ ) { + if (this.aRotation !== 0) { + var cos = Math.cos(this.aRotation); + var sin = Math.sin(this.aRotation); + var tx = x - this.aX; + var ty = y - this.aY; // Rotate the point about the center of the ellipse. - var groupID = objJSON.groups[ i ]; + x = tx * cos - ty * sin + this.aX; + y = tx * sin + ty * cos + this.aY; + } - if ( result.groups[ groupID ] === undefined ) { + return point.set(x, y); + }; - result.groups[ groupID ] = []; + EllipseCurve.prototype.copy = function (source) { + Curve.prototype.copy.call(this, source); + this.aX = source.aX; + this.aY = source.aY; + this.xRadius = source.xRadius; + this.yRadius = source.yRadius; + this.aStartAngle = source.aStartAngle; + this.aEndAngle = source.aEndAngle; + this.aClockwise = source.aClockwise; + this.aRotation = source.aRotation; + return this; + }; - } + EllipseCurve.prototype.toJSON = function () { + var data = Curve.prototype.toJSON.call(this); + data.aX = this.aX; + data.aY = this.aY; + data.xRadius = this.xRadius; + data.yRadius = this.yRadius; + data.aStartAngle = this.aStartAngle; + data.aEndAngle = this.aEndAngle; + data.aClockwise = this.aClockwise; + data.aRotation = this.aRotation; + return data; + }; - result.groups[ groupID ].push( objID ); + EllipseCurve.prototype.fromJSON = function (json) { + Curve.prototype.fromJSON.call(this, json); + this.aX = json.aX; + this.aY = json.aY; + this.xRadius = json.xRadius; + this.yRadius = json.yRadius; + this.aStartAngle = json.aStartAngle; + this.aEndAngle = json.aEndAngle; + this.aClockwise = json.aClockwise; + this.aRotation = json.aRotation; + return this; + }; - } + function ArcCurve(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { + EllipseCurve.call(this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); + this.type = 'ArcCurve'; + } - } + ArcCurve.prototype = Object.create(EllipseCurve.prototype); + ArcCurve.prototype.constructor = ArcCurve; + ArcCurve.prototype.isArcCurve = true; - } + /** + * Centripetal CatmullRom Curve - which is useful for avoiding + * cusps and self-intersections in non-uniform catmull rom curves. + * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf + * + * curve.type accepts centripetal(default), chordal and catmullrom + * curve.tension is used for catmullrom which defaults to 0.5 + */ - } + /* + Based on an optimized c++ solution in + - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/ + - http://ideone.com/NoEbVM - if ( object !== undefined && objJSON.children !== undefined ) { + This CubicPoly class could be used for reusing some variables and calculations, + but for three.js curve use, it could be possible inlined and flatten into a single function call + which can be placed in CurveUtils. + */ - handle_children( object, objJSON.children ); + function CubicPoly() { + var c0 = 0, + c1 = 0, + c2 = 0, + c3 = 0; + /* + * Compute coefficients for a cubic polynomial + * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 + * such that + * p(0) = x0, p(1) = x1 + * and + * p'(0) = t0, p'(1) = t1. + */ - } + function init(x0, x1, t0, t1) { + c0 = x0; + c1 = t0; + c2 = -3 * x0 + 3 * x1 - 2 * t0 - t1; + c3 = 2 * x0 - 2 * x1 + t0 + t1; + } + return { + initCatmullRom: function initCatmullRom(x0, x1, x2, x3, tension) { + init(x1, x2, tension * (x2 - x0), tension * (x3 - x1)); + }, + initNonuniformCatmullRom: function initNonuniformCatmullRom(x0, x1, x2, x3, dt0, dt1, dt2) { + // compute tangents when parameterized in [t1,t2] + var t1 = (x1 - x0) / dt0 - (x2 - x0) / (dt0 + dt1) + (x2 - x1) / dt1; + var t2 = (x2 - x1) / dt1 - (x3 - x1) / (dt1 + dt2) + (x3 - x2) / dt2; // rescale tangents for parametrization in [0,1] + + t1 *= dt1; + t2 *= dt1; + init(x1, x2, t1, t2); + }, + calc: function calc(t) { + var t2 = t * t; + var t3 = t2 * t; + return c0 + c1 * t + c2 * t2 + c3 * t3; } - }; + } // - function handle_mesh( geo, mat, id ) { - - result.geometries[ id ] = geo; - result.face_materials[ id ] = mat; - handle_objects(); - }; + var tmp = new Vector3(); + var px = new CubicPoly(), + py = new CubicPoly(), + pz = new CubicPoly(); - function handle_hierarchy( node, id, parent, material, obj ) { + function CatmullRomCurve3(points, closed, curveType, tension) { + Curve.call(this); + this.type = 'CatmullRomCurve3'; + this.points = points || []; + this.closed = closed || false; + this.curveType = curveType || 'centripetal'; + this.tension = tension !== undefined ? tension : 0.5; + } - var p = obj.position; - var r = obj.rotation; - var q = obj.quaternion; - var s = obj.scale; + CatmullRomCurve3.prototype = Object.create(Curve.prototype); + CatmullRomCurve3.prototype.constructor = CatmullRomCurve3; + CatmullRomCurve3.prototype.isCatmullRomCurve3 = true; - node.position.fromArray( p ); + CatmullRomCurve3.prototype.getPoint = function (t, optionalTarget) { + var point = optionalTarget || new Vector3(); + var points = this.points; + var l = points.length; + var p = (l - (this.closed ? 0 : 1)) * t; + var intPoint = Math.floor(p); + var weight = p - intPoint; - if ( q ) { + if (this.closed) { + intPoint += intPoint > 0 ? 0 : (Math.floor(Math.abs(intPoint) / l) + 1) * l; + } else if (weight === 0 && intPoint === l - 1) { + intPoint = l - 2; + weight = 1; + } - node.quaternion.fromArray( q ); + var p0, p3; // 4 points (p1 & p2 defined below) - } else { + if (this.closed || intPoint > 0) { + p0 = points[(intPoint - 1) % l]; + } else { + // extrapolate first point + tmp.subVectors(points[0], points[1]).add(points[0]); + p0 = tmp; + } - node.rotation.fromArray( r ); + var p1 = points[intPoint % l]; + var p2 = points[(intPoint + 1) % l]; - } + if (this.closed || intPoint + 2 < l) { + p3 = points[(intPoint + 2) % l]; + } else { + // extrapolate last point + tmp.subVectors(points[l - 1], points[l - 2]).add(points[l - 1]); + p3 = tmp; + } + + if (this.curveType === 'centripetal' || this.curveType === 'chordal') { + // init Centripetal / Chordal Catmull-Rom + var pow = this.curveType === 'chordal' ? 0.5 : 0.25; + var dt0 = Math.pow(p0.distanceToSquared(p1), pow); + var dt1 = Math.pow(p1.distanceToSquared(p2), pow); + var dt2 = Math.pow(p2.distanceToSquared(p3), pow); // safety check for repeated points + + if (dt1 < 1e-4) dt1 = 1.0; + if (dt0 < 1e-4) dt0 = dt1; + if (dt2 < 1e-4) dt2 = dt1; + px.initNonuniformCatmullRom(p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2); + py.initNonuniformCatmullRom(p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2); + pz.initNonuniformCatmullRom(p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2); + } else if (this.curveType === 'catmullrom') { + px.initCatmullRom(p0.x, p1.x, p2.x, p3.x, this.tension); + py.initCatmullRom(p0.y, p1.y, p2.y, p3.y, this.tension); + pz.initCatmullRom(p0.z, p1.z, p2.z, p3.z, this.tension); + } + + point.set(px.calc(weight), py.calc(weight), pz.calc(weight)); + return point; + }; - node.scale.fromArray( s ); + CatmullRomCurve3.prototype.copy = function (source) { + Curve.prototype.copy.call(this, source); + this.points = []; - // override children materials - // if object material was specified in JSON explicitly + for (var i = 0, l = source.points.length; i < l; i++) { + var point = source.points[i]; + this.points.push(point.clone()); + } - if ( material ) { + this.closed = source.closed; + this.curveType = source.curveType; + this.tension = source.tension; + return this; + }; - node.traverse( function ( child ) { + CatmullRomCurve3.prototype.toJSON = function () { + var data = Curve.prototype.toJSON.call(this); + data.points = []; - child.material = material; + for (var i = 0, l = this.points.length; i < l; i++) { + var point = this.points[i]; + data.points.push(point.toArray()); + } - } ); + data.closed = this.closed; + data.curveType = this.curveType; + data.tension = this.tension; + return data; + }; - } + CatmullRomCurve3.prototype.fromJSON = function (json) { + Curve.prototype.fromJSON.call(this, json); + this.points = []; - // override children visibility - // with root node visibility as specified in JSON + for (var i = 0, l = json.points.length; i < l; i++) { + var point = json.points[i]; + this.points.push(new Vector3().fromArray(point)); + } - var visible = ( obj.visible !== undefined ) ? obj.visible : true; + this.closed = json.closed; + this.curveType = json.curveType; + this.tension = json.tension; + return this; + }; - node.traverse( function ( child ) { + /** + * Bezier Curves formulas obtained from + * http://en.wikipedia.org/wiki/Bézier_curve + */ + function CatmullRom(t, p0, p1, p2, p3) { + var v0 = (p2 - p0) * 0.5; + var v1 = (p3 - p1) * 0.5; + var t2 = t * t; + var t3 = t * t2; + return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; + } // - child.visible = visible; - } ); + function QuadraticBezierP0(t, p) { + var k = 1 - t; + return k * k * p; + } - parent.add( node ); + function QuadraticBezierP1(t, p) { + return 2 * (1 - t) * t * p; + } - node.name = id; + function QuadraticBezierP2(t, p) { + return t * t * p; + } - result.objects[ id ] = node; - handle_objects(); + function QuadraticBezier(t, p0, p1, p2) { + return QuadraticBezierP0(t, p0) + QuadraticBezierP1(t, p1) + QuadraticBezierP2(t, p2); + } // - }; - function create_callback_geometry( id ) { + function CubicBezierP0(t, p) { + var k = 1 - t; + return k * k * k * p; + } - return function ( geo, mat ) { + function CubicBezierP1(t, p) { + var k = 1 - t; + return 3 * k * k * t * p; + } - geo.name = id; + function CubicBezierP2(t, p) { + return 3 * (1 - t) * t * t * p; + } - handle_mesh( geo, mat, id ); + function CubicBezierP3(t, p) { + return t * t * t * p; + } - counter_models -= 1; + function CubicBezier(t, p0, p1, p2, p3) { + return CubicBezierP0(t, p0) + CubicBezierP1(t, p1) + CubicBezierP2(t, p2) + CubicBezierP3(t, p3); + } - scope.onLoadComplete(); + function CubicBezierCurve(v0, v1, v2, v3) { + Curve.call(this); + this.type = 'CubicBezierCurve'; + this.v0 = v0 || new Vector2(); + this.v1 = v1 || new Vector2(); + this.v2 = v2 || new Vector2(); + this.v3 = v3 || new Vector2(); + } - async_callback_gate(); + CubicBezierCurve.prototype = Object.create(Curve.prototype); + CubicBezierCurve.prototype.constructor = CubicBezierCurve; + CubicBezierCurve.prototype.isCubicBezierCurve = true; - } + CubicBezierCurve.prototype.getPoint = function (t, optionalTarget) { + var point = optionalTarget || new Vector2(); + var v0 = this.v0, + v1 = this.v1, + v2 = this.v2, + v3 = this.v3; + point.set(CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y)); + return point; + }; - }; + CubicBezierCurve.prototype.copy = function (source) { + Curve.prototype.copy.call(this, source); + this.v0.copy(source.v0); + this.v1.copy(source.v1); + this.v2.copy(source.v2); + this.v3.copy(source.v3); + return this; + }; - function create_callback_hierachy( id, parent, material, obj ) { + CubicBezierCurve.prototype.toJSON = function () { + var data = Curve.prototype.toJSON.call(this); + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + data.v3 = this.v3.toArray(); + return data; + }; - return function ( event ) { + CubicBezierCurve.prototype.fromJSON = function (json) { + Curve.prototype.fromJSON.call(this, json); + this.v0.fromArray(json.v0); + this.v1.fromArray(json.v1); + this.v2.fromArray(json.v2); + this.v3.fromArray(json.v3); + return this; + }; - var result; + function CubicBezierCurve3(v0, v1, v2, v3) { + Curve.call(this); + this.type = 'CubicBezierCurve3'; + this.v0 = v0 || new Vector3(); + this.v1 = v1 || new Vector3(); + this.v2 = v2 || new Vector3(); + this.v3 = v3 || new Vector3(); + } + + CubicBezierCurve3.prototype = Object.create(Curve.prototype); + CubicBezierCurve3.prototype.constructor = CubicBezierCurve3; + CubicBezierCurve3.prototype.isCubicBezierCurve3 = true; + + CubicBezierCurve3.prototype.getPoint = function (t, optionalTarget) { + var point = optionalTarget || new Vector3(); + var v0 = this.v0, + v1 = this.v1, + v2 = this.v2, + v3 = this.v3; + point.set(CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y), CubicBezier(t, v0.z, v1.z, v2.z, v3.z)); + return point; + }; - // loaders which use EventDispatcher + CubicBezierCurve3.prototype.copy = function (source) { + Curve.prototype.copy.call(this, source); + this.v0.copy(source.v0); + this.v1.copy(source.v1); + this.v2.copy(source.v2); + this.v3.copy(source.v3); + return this; + }; - if ( event.content ) { + CubicBezierCurve3.prototype.toJSON = function () { + var data = Curve.prototype.toJSON.call(this); + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + data.v3 = this.v3.toArray(); + return data; + }; - result = event.content; + CubicBezierCurve3.prototype.fromJSON = function (json) { + Curve.prototype.fromJSON.call(this, json); + this.v0.fromArray(json.v0); + this.v1.fromArray(json.v1); + this.v2.fromArray(json.v2); + this.v3.fromArray(json.v3); + return this; + }; - // ColladaLoader + function LineCurve(v1, v2) { + Curve.call(this); + this.type = 'LineCurve'; + this.v1 = v1 || new Vector2(); + this.v2 = v2 || new Vector2(); + } - } else if ( event.dae ) { + LineCurve.prototype = Object.create(Curve.prototype); + LineCurve.prototype.constructor = LineCurve; + LineCurve.prototype.isLineCurve = true; - result = event.scene; + LineCurve.prototype.getPoint = function (t, optionalTarget) { + var point = optionalTarget || new Vector2(); + if (t === 1) { + point.copy(this.v2); + } else { + point.copy(this.v2).sub(this.v1); + point.multiplyScalar(t).add(this.v1); + } - // UTF8Loader + return point; + }; // Line curve is linear, so we can overwrite default getPointAt - } else { - result = event; + LineCurve.prototype.getPointAt = function (u, optionalTarget) { + return this.getPoint(u, optionalTarget); + }; - } + LineCurve.prototype.getTangent = function (t, optionalTarget) { + var tangent = optionalTarget || new Vector2(); + tangent.copy(this.v2).sub(this.v1).normalize(); + return tangent; + }; - handle_hierarchy( result, id, parent, material, obj ); + LineCurve.prototype.copy = function (source) { + Curve.prototype.copy.call(this, source); + this.v1.copy(source.v1); + this.v2.copy(source.v2); + return this; + }; - counter_models -= 1; + LineCurve.prototype.toJSON = function () { + var data = Curve.prototype.toJSON.call(this); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + return data; + }; - scope.onLoadComplete(); + LineCurve.prototype.fromJSON = function (json) { + Curve.prototype.fromJSON.call(this, json); + this.v1.fromArray(json.v1); + this.v2.fromArray(json.v2); + return this; + }; - async_callback_gate(); + function LineCurve3(v1, v2) { + Curve.call(this); + this.type = 'LineCurve3'; + this.v1 = v1 || new Vector3(); + this.v2 = v2 || new Vector3(); + } - } + LineCurve3.prototype = Object.create(Curve.prototype); + LineCurve3.prototype.constructor = LineCurve3; + LineCurve3.prototype.isLineCurve3 = true; - }; + LineCurve3.prototype.getPoint = function (t, optionalTarget) { + var point = optionalTarget || new Vector3(); - function create_callback_embed( id ) { + if (t === 1) { + point.copy(this.v2); + } else { + point.copy(this.v2).sub(this.v1); + point.multiplyScalar(t).add(this.v1); + } - return function ( geo, mat ) { + return point; + }; // Line curve is linear, so we can overwrite default getPointAt - geo.name = id; - result.geometries[ id ] = geo; - result.face_materials[ id ] = mat; + LineCurve3.prototype.getPointAt = function (u, optionalTarget) { + return this.getPoint(u, optionalTarget); + }; - } + LineCurve3.prototype.copy = function (source) { + Curve.prototype.copy.call(this, source); + this.v1.copy(source.v1); + this.v2.copy(source.v2); + return this; + }; - }; + LineCurve3.prototype.toJSON = function () { + var data = Curve.prototype.toJSON.call(this); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + return data; + }; - function async_callback_gate() { + LineCurve3.prototype.fromJSON = function (json) { + Curve.prototype.fromJSON.call(this, json); + this.v1.fromArray(json.v1); + this.v2.fromArray(json.v2); + return this; + }; - var progress = { + function QuadraticBezierCurve(v0, v1, v2) { + Curve.call(this); + this.type = 'QuadraticBezierCurve'; + this.v0 = v0 || new Vector2(); + this.v1 = v1 || new Vector2(); + this.v2 = v2 || new Vector2(); + } + + QuadraticBezierCurve.prototype = Object.create(Curve.prototype); + QuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve; + QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true; + + QuadraticBezierCurve.prototype.getPoint = function (t, optionalTarget) { + var point = optionalTarget || new Vector2(); + var v0 = this.v0, + v1 = this.v1, + v2 = this.v2; + point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y)); + return point; + }; - totalModels : total_models, - totalTextures : total_textures, - loadedModels : total_models - counter_models, - loadedTextures : total_textures - counter_textures + QuadraticBezierCurve.prototype.copy = function (source) { + Curve.prototype.copy.call(this, source); + this.v0.copy(source.v0); + this.v1.copy(source.v1); + this.v2.copy(source.v2); + return this; + }; - }; + QuadraticBezierCurve.prototype.toJSON = function () { + var data = Curve.prototype.toJSON.call(this); + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + return data; + }; - scope.callbackProgress( progress, result ); + QuadraticBezierCurve.prototype.fromJSON = function (json) { + Curve.prototype.fromJSON.call(this, json); + this.v0.fromArray(json.v0); + this.v1.fromArray(json.v1); + this.v2.fromArray(json.v2); + return this; + }; - scope.onLoadProgress(); + function QuadraticBezierCurve3(v0, v1, v2) { + Curve.call(this); + this.type = 'QuadraticBezierCurve3'; + this.v0 = v0 || new Vector3(); + this.v1 = v1 || new Vector3(); + this.v2 = v2 || new Vector3(); + } + + QuadraticBezierCurve3.prototype = Object.create(Curve.prototype); + QuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3; + QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true; + + QuadraticBezierCurve3.prototype.getPoint = function (t, optionalTarget) { + var point = optionalTarget || new Vector3(); + var v0 = this.v0, + v1 = this.v1, + v2 = this.v2; + point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y), QuadraticBezier(t, v0.z, v1.z, v2.z)); + return point; + }; - if ( counter_models === 0 && counter_textures === 0 ) { + QuadraticBezierCurve3.prototype.copy = function (source) { + Curve.prototype.copy.call(this, source); + this.v0.copy(source.v0); + this.v1.copy(source.v1); + this.v2.copy(source.v2); + return this; + }; - finalize(); - callbackFinished( result ); + QuadraticBezierCurve3.prototype.toJSON = function () { + var data = Curve.prototype.toJSON.call(this); + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + return data; + }; - } + QuadraticBezierCurve3.prototype.fromJSON = function (json) { + Curve.prototype.fromJSON.call(this, json); + this.v0.fromArray(json.v0); + this.v1.fromArray(json.v1); + this.v2.fromArray(json.v2); + return this; + }; - }; + function SplineCurve(points) { + Curve.call(this); + this.type = 'SplineCurve'; + this.points = points || []; + } + + SplineCurve.prototype = Object.create(Curve.prototype); + SplineCurve.prototype.constructor = SplineCurve; + SplineCurve.prototype.isSplineCurve = true; + + SplineCurve.prototype.getPoint = function (t, optionalTarget) { + var point = optionalTarget || new Vector2(); + var points = this.points; + var p = (points.length - 1) * t; + var intPoint = Math.floor(p); + var weight = p - intPoint; + var p0 = points[intPoint === 0 ? intPoint : intPoint - 1]; + var p1 = points[intPoint]; + var p2 = points[intPoint > points.length - 2 ? points.length - 1 : intPoint + 1]; + var p3 = points[intPoint > points.length - 3 ? points.length - 1 : intPoint + 2]; + point.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y)); + return point; + }; - function finalize() { + SplineCurve.prototype.copy = function (source) { + Curve.prototype.copy.call(this, source); + this.points = []; - // take care of targets which could be asynchronously loaded objects + for (var i = 0, l = source.points.length; i < l; i++) { + var point = source.points[i]; + this.points.push(point.clone()); + } - for ( var i = 0; i < target_array.length; i ++ ) { + return this; + }; - var ta = target_array[ i ]; + SplineCurve.prototype.toJSON = function () { + var data = Curve.prototype.toJSON.call(this); + data.points = []; - var target = result.objects[ ta.targetName ]; + for (var i = 0, l = this.points.length; i < l; i++) { + var point = this.points[i]; + data.points.push(point.toArray()); + } - if ( target ) { + return data; + }; - ta.object.target = target; + SplineCurve.prototype.fromJSON = function (json) { + Curve.prototype.fromJSON.call(this, json); + this.points = []; - } else { + for (var i = 0, l = json.points.length; i < l; i++) { + var point = json.points[i]; + this.points.push(new Vector2().fromArray(point)); + } - // if there was error and target of specified name doesn't exist in the scene file - // create instead dummy target - // (target must be added to scene explicitly as parent is already added) + return this; + }; - ta.object.target = new THREE.Object3D(); - result.scene.add( ta.object.target ); + var Curves = /*#__PURE__*/Object.freeze({ + __proto__: null, + ArcCurve: ArcCurve, + CatmullRomCurve3: CatmullRomCurve3, + CubicBezierCurve: CubicBezierCurve, + CubicBezierCurve3: CubicBezierCurve3, + EllipseCurve: EllipseCurve, + LineCurve: LineCurve, + LineCurve3: LineCurve3, + QuadraticBezierCurve: QuadraticBezierCurve, + QuadraticBezierCurve3: QuadraticBezierCurve3, + SplineCurve: SplineCurve + }); + + /************************************************************** + * Curved Path - a curve path is simply a array of connected + * curves, but retains the api of a curve + **************************************************************/ + + function CurvePath() { + Curve.call(this); + this.type = 'CurvePath'; + this.curves = []; + this.autoClose = false; // Automatically closes the path + } + + CurvePath.prototype = Object.assign(Object.create(Curve.prototype), { + constructor: CurvePath, + add: function add(curve) { + this.curves.push(curve); + }, + closePath: function closePath() { + // Add a line curve if start and end of lines are not connected + var startPoint = this.curves[0].getPoint(0); + var endPoint = this.curves[this.curves.length - 1].getPoint(1); + if (!startPoint.equals(endPoint)) { + this.curves.push(new LineCurve(endPoint, startPoint)); + } + }, + // To get accurate point with reference to + // entire path distance at time t, + // following has to be done: + // 1. Length of each sub path have to be known + // 2. Locate and identify type of curve + // 3. Get t for the curve + // 4. Return curve.getPointAt(t') + getPoint: function getPoint(t) { + var d = t * this.getLength(); + var curveLengths = this.getCurveLengths(); + var i = 0; // To think about boundaries points. + + while (i < curveLengths.length) { + if (curveLengths[i] >= d) { + var diff = curveLengths[i] - d; + var curve = this.curves[i]; + var segmentLength = curve.getLength(); + var u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; + return curve.getPointAt(u); } - ta.object.target.userData.targetInverse = ta.object; - + i++; } - }; - - var callbackTexture = function ( count ) { - - counter_textures -= count; - async_callback_gate(); - - scope.onLoadComplete(); - - }; - - // must use this instead of just directly calling callbackTexture - // because of closure in the calling context loop + return null; // loop where sum != 0, sum > d , sum+1 1 && !points[points.length - 1].equals(points[0])) { + points.push(points[0]); + } - for ( var objChildID in objJSON.children ) { + return points; + }, + copy: function copy(source) { + Curve.prototype.copy.call(this, source); + this.curves = []; - traverse_json_hierarchy( objJSON.children[ objChildID ], callback ); + for (var i = 0, l = source.curves.length; i < l; i++) { + var curve = source.curves[i]; + this.curves.push(curve.clone()); + } - } + this.autoClose = source.autoClose; + return this; + }, + toJSON: function toJSON() { + var data = Curve.prototype.toJSON.call(this); + data.autoClose = this.autoClose; + data.curves = []; + for (var i = 0, l = this.curves.length; i < l; i++) { + var curve = this.curves[i]; + data.curves.push(curve.toJSON()); } - }; + return data; + }, + fromJSON: function fromJSON(json) { + Curve.prototype.fromJSON.call(this, json); + this.autoClose = json.autoClose; + this.curves = []; - // first go synchronous elements + for (var i = 0, l = json.curves.length; i < l; i++) { + var curve = json.curves[i]; + this.curves.push(new Curves[curve.type]().fromJSON(curve)); + } - // fogs + return this; + } + }); - var fogID, fogJSON; + function Path(points) { + CurvePath.call(this); + this.type = 'Path'; + this.currentPoint = new Vector2(); - for ( fogID in data.fogs ) { + if (points) { + this.setFromPoints(points); + } + } - fogJSON = data.fogs[ fogID ]; + Path.prototype = Object.assign(Object.create(CurvePath.prototype), { + constructor: Path, + setFromPoints: function setFromPoints(points) { + this.moveTo(points[0].x, points[0].y); - if ( fogJSON.type === "linear" ) { + for (var i = 1, l = points.length; i < l; i++) { + this.lineTo(points[i].x, points[i].y); + } - fog = new THREE.Fog( 0x000000, fogJSON.near, fogJSON.far ); + return this; + }, + moveTo: function moveTo(x, y) { + this.currentPoint.set(x, y); // TODO consider referencing vectors instead of copying? - } else if ( fogJSON.type === "exp2" ) { + return this; + }, + lineTo: function lineTo(x, y) { + var curve = new LineCurve(this.currentPoint.clone(), new Vector2(x, y)); + this.curves.push(curve); + this.currentPoint.set(x, y); + return this; + }, + quadraticCurveTo: function quadraticCurveTo(aCPx, aCPy, aX, aY) { + var curve = new QuadraticBezierCurve(this.currentPoint.clone(), new Vector2(aCPx, aCPy), new Vector2(aX, aY)); + this.curves.push(curve); + this.currentPoint.set(aX, aY); + return this; + }, + bezierCurveTo: function bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { + var curve = new CubicBezierCurve(this.currentPoint.clone(), new Vector2(aCP1x, aCP1y), new Vector2(aCP2x, aCP2y), new Vector2(aX, aY)); + this.curves.push(curve); + this.currentPoint.set(aX, aY); + return this; + }, + splineThru: function splineThru(pts + /*Array of Vector*/ + ) { + var npts = [this.currentPoint.clone()].concat(pts); + var curve = new SplineCurve(npts); + this.curves.push(curve); + this.currentPoint.copy(pts[pts.length - 1]); + return this; + }, + arc: function arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { + var x0 = this.currentPoint.x; + var y0 = this.currentPoint.y; + this.absarc(aX + x0, aY + y0, aRadius, aStartAngle, aEndAngle, aClockwise); + return this; + }, + absarc: function absarc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { + this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); + return this; + }, + ellipse: function ellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { + var x0 = this.currentPoint.x; + var y0 = this.currentPoint.y; + this.absellipse(aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); + return this; + }, + absellipse: function absellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { + var curve = new EllipseCurve(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); - fog = new THREE.FogExp2( 0x000000, fogJSON.density ); + if (this.curves.length > 0) { + // if a previous curve is present, attempt to join + var firstPoint = curve.getPoint(0); + if (!firstPoint.equals(this.currentPoint)) { + this.lineTo(firstPoint.x, firstPoint.y); + } } - color = fogJSON.color; - fog.color.setRGB( color[0], color[1], color[2] ); - - result.fogs[ fogID ] = fog; - + this.curves.push(curve); + var lastPoint = curve.getPoint(1); + this.currentPoint.copy(lastPoint); + return this; + }, + copy: function copy(source) { + CurvePath.prototype.copy.call(this, source); + this.currentPoint.copy(source.currentPoint); + return this; + }, + toJSON: function toJSON() { + var data = CurvePath.prototype.toJSON.call(this); + data.currentPoint = this.currentPoint.toArray(); + return data; + }, + fromJSON: function fromJSON(json) { + CurvePath.prototype.fromJSON.call(this, json); + this.currentPoint.fromArray(json.currentPoint); + return this; } + }); - // now come potentially asynchronous elements - - // geometries + function Shape(points) { + Path.call(this, points); + this.uuid = MathUtils.generateUUID(); + this.type = 'Shape'; + this.holes = []; + } - // count how many geometries will be loaded asynchronously + Shape.prototype = Object.assign(Object.create(Path.prototype), { + constructor: Shape, + getPointsHoles: function getPointsHoles(divisions) { + var holesPts = []; - var geoID, geoJSON; + for (var i = 0, l = this.holes.length; i < l; i++) { + holesPts[i] = this.holes[i].getPoints(divisions); + } - for ( geoID in data.geometries ) { + return holesPts; + }, + // get points of shape and holes (keypoints based on segments parameter) + extractPoints: function extractPoints(divisions) { + return { + shape: this.getPoints(divisions), + holes: this.getPointsHoles(divisions) + }; + }, + copy: function copy(source) { + Path.prototype.copy.call(this, source); + this.holes = []; - geoJSON = data.geometries[ geoID ]; + for (var i = 0, l = source.holes.length; i < l; i++) { + var hole = source.holes[i]; + this.holes.push(hole.clone()); + } - if ( geoJSON.type in this.geometryHandlers ) { + return this; + }, + toJSON: function toJSON() { + var data = Path.prototype.toJSON.call(this); + data.uuid = this.uuid; + data.holes = []; - counter_models += 1; + for (var i = 0, l = this.holes.length; i < l; i++) { + var hole = this.holes[i]; + data.holes.push(hole.toJSON()); + } - scope.onLoadStart(); + return data; + }, + fromJSON: function fromJSON(json) { + Path.prototype.fromJSON.call(this, json); + this.uuid = json.uuid; + this.holes = []; + for (var i = 0, l = json.holes.length; i < l; i++) { + var hole = json.holes[i]; + this.holes.push(new Path().fromJSON(hole)); } + return this; } + }); - // count how many hierarchies will be loaded asynchronously - - for ( var objID in data.objects ) { - - traverse_json_hierarchy( data.objects[ objID ], function ( objJSON ) { - - if ( objJSON.type && ( objJSON.type in scope.hierarchyHandlers ) ) { + function Light(color, intensity) { + Object3D.call(this); + this.type = 'Light'; + this.color = new Color(color); + this.intensity = intensity !== undefined ? intensity : 1; + } - counter_models += 1; + Light.prototype = Object.assign(Object.create(Object3D.prototype), { + constructor: Light, + isLight: true, + copy: function copy(source) { + Object3D.prototype.copy.call(this, source); + this.color.copy(source.color); + this.intensity = source.intensity; + return this; + }, + toJSON: function toJSON(meta) { + var data = Object3D.prototype.toJSON.call(this, meta); + data.object.color = this.color.getHex(); + data.object.intensity = this.intensity; + if (this.groundColor !== undefined) data.object.groundColor = this.groundColor.getHex(); + if (this.distance !== undefined) data.object.distance = this.distance; + if (this.angle !== undefined) data.object.angle = this.angle; + if (this.decay !== undefined) data.object.decay = this.decay; + if (this.penumbra !== undefined) data.object.penumbra = this.penumbra; + if (this.shadow !== undefined) data.object.shadow = this.shadow.toJSON(); + return data; + } + }); + + function HemisphereLight(skyColor, groundColor, intensity) { + Light.call(this, skyColor, intensity); + this.type = 'HemisphereLight'; + this.position.copy(Object3D.DefaultUp); + this.updateMatrix(); + this.groundColor = new Color(groundColor); + } + + HemisphereLight.prototype = Object.assign(Object.create(Light.prototype), { + constructor: HemisphereLight, + isHemisphereLight: true, + copy: function copy(source) { + Light.prototype.copy.call(this, source); + this.groundColor.copy(source.groundColor); + return this; + } + }); + + function LightShadow(camera) { + this.camera = camera; + this.bias = 0; + this.normalBias = 0; + this.radius = 1; + this.mapSize = new Vector2(512, 512); + this.map = null; + this.mapPass = null; + this.matrix = new Matrix4(); + this.autoUpdate = true; + this.needsUpdate = false; + this._frustum = new Frustum(); + this._frameExtents = new Vector2(1, 1); + this._viewportCount = 1; + this._viewports = [new Vector4(0, 0, 1, 1)]; + } + + Object.assign(LightShadow.prototype, { + _projScreenMatrix: new Matrix4(), + _lightPositionWorld: new Vector3(), + _lookTarget: new Vector3(), + getViewportCount: function getViewportCount() { + return this._viewportCount; + }, + getFrustum: function getFrustum() { + return this._frustum; + }, + updateMatrices: function updateMatrices(light) { + var shadowCamera = this.camera, + shadowMatrix = this.matrix, + projScreenMatrix = this._projScreenMatrix, + lookTarget = this._lookTarget, + lightPositionWorld = this._lightPositionWorld; + lightPositionWorld.setFromMatrixPosition(light.matrixWorld); + shadowCamera.position.copy(lightPositionWorld); + lookTarget.setFromMatrixPosition(light.target.matrixWorld); + shadowCamera.lookAt(lookTarget); + shadowCamera.updateMatrixWorld(); + projScreenMatrix.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse); - scope.onLoadStart(); + this._frustum.setFromProjectionMatrix(projScreenMatrix); - } - - }); + shadowMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0); + shadowMatrix.multiply(shadowCamera.projectionMatrix); + shadowMatrix.multiply(shadowCamera.matrixWorldInverse); + }, + getViewport: function getViewport(viewportIndex) { + return this._viewports[viewportIndex]; + }, + getFrameExtents: function getFrameExtents() { + return this._frameExtents; + }, + copy: function copy(source) { + this.camera = source.camera.clone(); + this.bias = source.bias; + this.radius = source.radius; + this.mapSize.copy(source.mapSize); + return this; + }, + clone: function clone() { + return new this.constructor().copy(this); + }, + toJSON: function toJSON() { + var object = {}; + if (this.bias !== 0) object.bias = this.bias; + if (this.normalBias !== 0) object.normalBias = this.normalBias; + if (this.radius !== 1) object.radius = this.radius; + if (this.mapSize.x !== 512 || this.mapSize.y !== 512) object.mapSize = this.mapSize.toArray(); + object.camera = this.camera.toJSON(false).object; + delete object.camera.matrix; + return object; + } + }); + + function SpotLightShadow() { + LightShadow.call(this, new PerspectiveCamera(50, 1, 0.5, 500)); + this.focus = 1; + } + + SpotLightShadow.prototype = Object.assign(Object.create(LightShadow.prototype), { + constructor: SpotLightShadow, + isSpotLightShadow: true, + updateMatrices: function updateMatrices(light) { + var camera = this.camera; + var fov = MathUtils.RAD2DEG * 2 * light.angle * this.focus; + var aspect = this.mapSize.width / this.mapSize.height; + var far = light.distance || camera.far; + + if (fov !== camera.fov || aspect !== camera.aspect || far !== camera.far) { + camera.fov = fov; + camera.aspect = aspect; + camera.far = far; + camera.updateProjectionMatrix(); + } + + LightShadow.prototype.updateMatrices.call(this, light); + } + }); + + function SpotLight(color, intensity, distance, angle, penumbra, decay) { + Light.call(this, color, intensity); + this.type = 'SpotLight'; + this.position.copy(Object3D.DefaultUp); + this.updateMatrix(); + this.target = new Object3D(); + Object.defineProperty(this, 'power', { + get: function get() { + // intensity = power per solid angle. + // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf + return this.intensity * Math.PI; + }, + set: function set(power) { + // intensity = power per solid angle. + // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf + this.intensity = power / Math.PI; + } + }); + this.distance = distance !== undefined ? distance : 0; + this.angle = angle !== undefined ? angle : Math.PI / 3; + this.penumbra = penumbra !== undefined ? penumbra : 0; + this.decay = decay !== undefined ? decay : 1; // for physically correct lights, should be 2. + + this.shadow = new SpotLightShadow(); + } + + SpotLight.prototype = Object.assign(Object.create(Light.prototype), { + constructor: SpotLight, + isSpotLight: true, + copy: function copy(source) { + Light.prototype.copy.call(this, source); + this.distance = source.distance; + this.angle = source.angle; + this.penumbra = source.penumbra; + this.decay = source.decay; + this.target = source.target.clone(); + this.shadow = source.shadow.clone(); + return this; + } + }); + function PointLightShadow() { + LightShadow.call(this, new PerspectiveCamera(90, 1, 0.5, 500)); + this._frameExtents = new Vector2(4, 2); + this._viewportCount = 6; + this._viewports = [// These viewports map a cube-map onto a 2D texture with the + // following orientation: + // + // xzXZ + // y Y + // + // X - Positive x direction + // x - Negative x direction + // Y - Positive y direction + // y - Negative y direction + // Z - Positive z direction + // z - Negative z direction + // positive X + new Vector4(2, 1, 1, 1), // negative X + new Vector4(0, 1, 1, 1), // positive Z + new Vector4(3, 1, 1, 1), // negative Z + new Vector4(1, 1, 1, 1), // positive Y + new Vector4(3, 0, 1, 1), // negative Y + new Vector4(1, 0, 1, 1)]; + this._cubeDirections = [new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1), new Vector3(0, 1, 0), new Vector3(0, -1, 0)]; + this._cubeUps = [new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1)]; + } + + PointLightShadow.prototype = Object.assign(Object.create(LightShadow.prototype), { + constructor: PointLightShadow, + isPointLightShadow: true, + updateMatrices: function updateMatrices(light, viewportIndex) { + if (viewportIndex === undefined) viewportIndex = 0; + var camera = this.camera, + shadowMatrix = this.matrix, + lightPositionWorld = this._lightPositionWorld, + lookTarget = this._lookTarget, + projScreenMatrix = this._projScreenMatrix; + lightPositionWorld.setFromMatrixPosition(light.matrixWorld); + camera.position.copy(lightPositionWorld); + lookTarget.copy(camera.position); + lookTarget.add(this._cubeDirections[viewportIndex]); + camera.up.copy(this._cubeUps[viewportIndex]); + camera.lookAt(lookTarget); + camera.updateMatrixWorld(); + shadowMatrix.makeTranslation(-lightPositionWorld.x, -lightPositionWorld.y, -lightPositionWorld.z); + projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); + + this._frustum.setFromProjectionMatrix(projScreenMatrix); + } + }); + + function PointLight(color, intensity, distance, decay) { + Light.call(this, color, intensity); + this.type = 'PointLight'; + Object.defineProperty(this, 'power', { + get: function get() { + // intensity = power per solid angle. + // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf + return this.intensity * 4 * Math.PI; + }, + set: function set(power) { + // intensity = power per solid angle. + // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf + this.intensity = power / (4 * Math.PI); + } + }); + this.distance = distance !== undefined ? distance : 0; + this.decay = decay !== undefined ? decay : 1; // for physically correct lights, should be 2. + + this.shadow = new PointLightShadow(); + } + + PointLight.prototype = Object.assign(Object.create(Light.prototype), { + constructor: PointLight, + isPointLight: true, + copy: function copy(source) { + Light.prototype.copy.call(this, source); + this.distance = source.distance; + this.decay = source.decay; + this.shadow = source.shadow.clone(); + return this; } + }); + + function OrthographicCamera(left, right, top, bottom, near, far) { + Camera.call(this); + this.type = 'OrthographicCamera'; + this.zoom = 1; + this.view = null; + this.left = left !== undefined ? left : -1; + this.right = right !== undefined ? right : 1; + this.top = top !== undefined ? top : 1; + this.bottom = bottom !== undefined ? bottom : -1; + this.near = near !== undefined ? near : 0.1; + this.far = far !== undefined ? far : 2000; + this.updateProjectionMatrix(); + } + + OrthographicCamera.prototype = Object.assign(Object.create(Camera.prototype), { + constructor: OrthographicCamera, + isOrthographicCamera: true, + copy: function copy(source, recursive) { + Camera.prototype.copy.call(this, 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: function 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 + }; + } - total_models = counter_models; + 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: function clearViewOffset() { + if (this.view !== null) { + this.view.enabled = false; + } + + this.updateProjectionMatrix(); + }, + updateProjectionMatrix: function updateProjectionMatrix() { + var dx = (this.right - this.left) / (2 * this.zoom); + var dy = (this.top - this.bottom) / (2 * this.zoom); + var cx = (this.right + this.left) / 2; + var cy = (this.top + this.bottom) / 2; + var left = cx - dx; + var right = cx + dx; + var top = cy + dy; + var bottom = cy - dy; + + if (this.view !== null && this.view.enabled) { + var scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom; + var 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.getInverse(this.projectionMatrix); + }, + toJSON: function toJSON(meta) { + var data = Object3D.prototype.toJSON.call(this, 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; + } + }); + + function DirectionalLightShadow() { + LightShadow.call(this, new OrthographicCamera(-5, 5, 5, -5, 0.5, 500)); + } + + DirectionalLightShadow.prototype = Object.assign(Object.create(LightShadow.prototype), { + constructor: DirectionalLightShadow, + isDirectionalLightShadow: true, + updateMatrices: function updateMatrices(light) { + LightShadow.prototype.updateMatrices.call(this, light); + } + }); + + function DirectionalLight(color, intensity) { + Light.call(this, color, intensity); + this.type = 'DirectionalLight'; + this.position.copy(Object3D.DefaultUp); + this.updateMatrix(); + this.target = new Object3D(); + this.shadow = new DirectionalLightShadow(); + } + + DirectionalLight.prototype = Object.assign(Object.create(Light.prototype), { + constructor: DirectionalLight, + isDirectionalLight: true, + copy: function copy(source) { + Light.prototype.copy.call(this, source); + this.target = source.target.clone(); + this.shadow = source.shadow.clone(); + return this; + } + }); - for ( geoID in data.geometries ) { + function AmbientLight(color, intensity) { + Light.call(this, color, intensity); + this.type = 'AmbientLight'; + } - geoJSON = data.geometries[ geoID ]; + AmbientLight.prototype = Object.assign(Object.create(Light.prototype), { + constructor: AmbientLight, + isAmbientLight: true + }); - if ( geoJSON.type === "cube" ) { + function RectAreaLight(color, intensity, width, height) { + Light.call(this, color, intensity); + this.type = 'RectAreaLight'; + this.width = width !== undefined ? width : 10; + this.height = height !== undefined ? height : 10; + } - geometry = new THREE.BoxGeometry( geoJSON.width, geoJSON.height, geoJSON.depth, geoJSON.widthSegments, geoJSON.heightSegments, geoJSON.depthSegments ); - geometry.name = geoID; - result.geometries[ geoID ] = geometry; + RectAreaLight.prototype = Object.assign(Object.create(Light.prototype), { + constructor: RectAreaLight, + isRectAreaLight: true, + copy: function copy(source) { + Light.prototype.copy.call(this, source); + this.width = source.width; + this.height = source.height; + return this; + }, + toJSON: function toJSON(meta) { + var data = Light.prototype.toJSON.call(this, meta); + data.object.width = this.width; + data.object.height = this.height; + return data; + } + }); - } else if ( geoJSON.type === "plane" ) { + /** + * Primary reference: + * https://graphics.stanford.edu/papers/envmap/envmap.pdf + * + * Secondary reference: + * https://www.ppsloan.org/publications/StupidSH36.pdf + */ + // 3-band SH defined by 9 coefficients - geometry = new THREE.PlaneGeometry( geoJSON.width, geoJSON.height, geoJSON.widthSegments, geoJSON.heightSegments ); - geometry.name = geoID; - result.geometries[ geoID ] = geometry; + var SphericalHarmonics3 = /*#__PURE__*/function () { + function SphericalHarmonics3() { + Object.defineProperty(this, 'isSphericalHarmonics3', { + value: true + }); + this.coefficients = []; - } else if ( geoJSON.type === "sphere" ) { + for (var i = 0; i < 9; i++) { + this.coefficients.push(new Vector3()); + } + } - geometry = new THREE.SphereGeometry( geoJSON.radius, geoJSON.widthSegments, geoJSON.heightSegments ); - geometry.name = geoID; - result.geometries[ geoID ] = geometry; + var _proto = SphericalHarmonics3.prototype; - } else if ( geoJSON.type === "cylinder" ) { + _proto.set = function set(coefficients) { + for (var i = 0; i < 9; i++) { + this.coefficients[i].copy(coefficients[i]); + } - geometry = new THREE.CylinderGeometry( geoJSON.topRad, geoJSON.botRad, geoJSON.height, geoJSON.radSegs, geoJSON.heightSegs ); - geometry.name = geoID; - result.geometries[ geoID ] = geometry; + return this; + }; - } else if ( geoJSON.type === "torus" ) { + _proto.zero = function zero() { + for (var i = 0; i < 9; i++) { + this.coefficients[i].set(0, 0, 0); + } - geometry = new THREE.TorusGeometry( geoJSON.radius, geoJSON.tube, geoJSON.segmentsR, geoJSON.segmentsT ); - geometry.name = geoID; - result.geometries[ geoID ] = geometry; + return this; + } // get the radiance in the direction of the normal + // target is a Vector3 + ; + + _proto.getAt = function getAt(normal, target) { + // normal is assumed to be unit length + var x = normal.x, + y = normal.y, + z = normal.z; + var coeff = this.coefficients; // band 0 + + target.copy(coeff[0]).multiplyScalar(0.282095); // band 1 + + target.addScaledVector(coeff[1], 0.488603 * y); + target.addScaledVector(coeff[2], 0.488603 * z); + target.addScaledVector(coeff[3], 0.488603 * x); // band 2 + + target.addScaledVector(coeff[4], 1.092548 * (x * y)); + target.addScaledVector(coeff[5], 1.092548 * (y * z)); + target.addScaledVector(coeff[6], 0.315392 * (3.0 * z * z - 1.0)); + target.addScaledVector(coeff[7], 1.092548 * (x * z)); + target.addScaledVector(coeff[8], 0.546274 * (x * x - y * y)); + return target; + } // get the irradiance (radiance convolved with cosine lobe) in the direction of the normal + // target is a Vector3 + // https://graphics.stanford.edu/papers/envmap/envmap.pdf + ; + + _proto.getIrradianceAt = function getIrradianceAt(normal, target) { + // normal is assumed to be unit length + var x = normal.x, + y = normal.y, + z = normal.z; + var coeff = this.coefficients; // band 0 + + target.copy(coeff[0]).multiplyScalar(0.886227); // π * 0.282095 + // band 1 + + target.addScaledVector(coeff[1], 2.0 * 0.511664 * y); // ( 2 * π / 3 ) * 0.488603 + + target.addScaledVector(coeff[2], 2.0 * 0.511664 * z); + target.addScaledVector(coeff[3], 2.0 * 0.511664 * x); // band 2 + + target.addScaledVector(coeff[4], 2.0 * 0.429043 * x * y); // ( π / 4 ) * 1.092548 + + target.addScaledVector(coeff[5], 2.0 * 0.429043 * y * z); + target.addScaledVector(coeff[6], 0.743125 * z * z - 0.247708); // ( π / 4 ) * 0.315392 * 3 + + target.addScaledVector(coeff[7], 2.0 * 0.429043 * x * z); + target.addScaledVector(coeff[8], 0.429043 * (x * x - y * y)); // ( π / 4 ) * 0.546274 + + return target; + }; - } else if ( geoJSON.type === "icosahedron" ) { + _proto.add = function add(sh) { + for (var i = 0; i < 9; i++) { + this.coefficients[i].add(sh.coefficients[i]); + } - geometry = new THREE.IcosahedronGeometry( geoJSON.radius, geoJSON.subdivisions ); - geometry.name = geoID; - result.geometries[ geoID ] = geometry; + return this; + }; - } else if ( geoJSON.type in this.geometryHandlers ) { + _proto.addScaledSH = function addScaledSH(sh, s) { + for (var i = 0; i < 9; i++) { + this.coefficients[i].addScaledVector(sh.coefficients[i], s); + } - var loaderParameters = {}; + return this; + }; - for ( var parType in geoJSON ) { + _proto.scale = function scale(s) { + for (var i = 0; i < 9; i++) { + this.coefficients[i].multiplyScalar(s); + } - if ( parType !== "type" && parType !== "url" ) { + return this; + }; - loaderParameters[ parType ] = geoJSON[ parType ]; + _proto.lerp = function lerp(sh, alpha) { + for (var i = 0; i < 9; i++) { + this.coefficients[i].lerp(sh.coefficients[i], alpha); + } - } + return this; + }; + _proto.equals = function equals(sh) { + for (var i = 0; i < 9; i++) { + if (!this.coefficients[i].equals(sh.coefficients[i])) { + return false; } + } - var loader = this.geometryHandlers[ geoJSON.type ][ "loaderObject" ]; - loader.load( get_url( geoJSON.url, data.urlBaseType ), create_callback_geometry( geoID ), loaderParameters ); + return true; + }; - } else if ( geoJSON.type === "embedded" ) { + _proto.copy = function copy(sh) { + return this.set(sh.coefficients); + }; - var modelJson = data.embeds[ geoJSON.id ], - texture_path = ""; + _proto.clone = function clone() { + return new this.constructor().copy(this); + }; - // pass metadata along to jsonLoader so it knows the format version + _proto.fromArray = function fromArray(array, offset) { + if (offset === void 0) { + offset = 0; + } - modelJson.metadata = data.metadata; + var coefficients = this.coefficients; - if ( modelJson ) { + for (var i = 0; i < 9; i++) { + coefficients[i].fromArray(array, offset + i * 3); + } - var jsonLoader = this.geometryHandlers[ "ascii" ][ "loaderObject" ]; - var model = jsonLoader.parse( modelJson, texture_path ); - create_callback_embed( geoID )( model.geometry, model.materials ); + return this; + }; - } + _proto.toArray = function toArray(array, offset) { + if (array === void 0) { + array = []; + } + if (offset === void 0) { + offset = 0; } - } + var coefficients = this.coefficients; - // textures + for (var i = 0; i < 9; i++) { + coefficients[i].toArray(array, offset + i * 3); + } - // count how many textures will be loaded asynchronously + return array; + } // evaluate the basis functions + // shBasis is an Array[ 9 ] + ; + + SphericalHarmonics3.getBasisAt = function getBasisAt(normal, shBasis) { + // normal is assumed to be unit length + var x = normal.x, + y = normal.y, + z = normal.z; // band 0 + + shBasis[0] = 0.282095; // band 1 + + shBasis[1] = 0.488603 * y; + shBasis[2] = 0.488603 * z; + shBasis[3] = 0.488603 * x; // band 2 + + shBasis[4] = 1.092548 * x * y; + shBasis[5] = 1.092548 * y * z; + shBasis[6] = 0.315392 * (3 * z * z - 1); + shBasis[7] = 1.092548 * x * z; + shBasis[8] = 0.546274 * (x * x - y * y); + }; - var textureID, textureJSON; + return SphericalHarmonics3; + }(); - for ( textureID in data.textures ) { + function LightProbe(sh, intensity) { + Light.call(this, undefined, intensity); + this.type = 'LightProbe'; + this.sh = sh !== undefined ? sh : new SphericalHarmonics3(); + } - textureJSON = data.textures[ textureID ]; + LightProbe.prototype = Object.assign(Object.create(Light.prototype), { + constructor: LightProbe, + isLightProbe: true, + copy: function copy(source) { + Light.prototype.copy.call(this, source); + this.sh.copy(source.sh); + return this; + }, + fromJSON: function fromJSON(json) { + this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON(); - if ( textureJSON.url instanceof Array ) { + this.sh.fromArray(json.sh); + return this; + }, + toJSON: function toJSON(meta) { + var data = Light.prototype.toJSON.call(this, meta); + data.object.sh = this.sh.toArray(); + return data; + } + }); - counter_textures += textureJSON.url.length; + function MaterialLoader(manager) { + Loader.call(this, manager); + this.textures = {}; + } - for( var n = 0; n < textureJSON.url.length; n ++ ) { + MaterialLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: MaterialLoader, + load: function load(url, onLoad, onProgress, onError) { + var scope = this; + var loader = new FileLoader(scope.manager); + loader.setPath(scope.path); + loader.setRequestHeader(scope.requestHeader); + loader.setWithCredentials(scope.withCredentials); + loader.load(url, function (text) { + try { + onLoad(scope.parse(JSON.parse(text))); + } catch (e) { + if (onError) { + onError(e); + } else { + console.error(e); + } - scope.onLoadStart(); + scope.manager.itemError(url); + } + }, onProgress, onError); + }, + parse: function parse(json) { + var textures = this.textures; + function getTexture(name) { + if (textures[name] === undefined) { + console.warn('THREE.MaterialLoader: Undefined texture', name); } - } else { + return textures[name]; + } + + var material = new Materials[json.type](); + if (json.uuid !== undefined) material.uuid = json.uuid; + if (json.name !== undefined) material.name = json.name; + if (json.color !== undefined && material.color !== undefined) material.color.setHex(json.color); + if (json.roughness !== undefined) material.roughness = json.roughness; + if (json.metalness !== undefined) material.metalness = json.metalness; + if (json.sheen !== undefined) material.sheen = new Color().setHex(json.sheen); + if (json.emissive !== undefined && material.emissive !== undefined) material.emissive.setHex(json.emissive); + if (json.specular !== undefined && material.specular !== undefined) material.specular.setHex(json.specular); + if (json.shininess !== undefined) material.shininess = json.shininess; + if (json.clearcoat !== undefined) material.clearcoat = json.clearcoat; + if (json.clearcoatRoughness !== undefined) material.clearcoatRoughness = json.clearcoatRoughness; + if (json.fog !== undefined) material.fog = json.fog; + if (json.flatShading !== undefined) material.flatShading = json.flatShading; + if (json.blending !== undefined) material.blending = json.blending; + if (json.combine !== undefined) material.combine = json.combine; + if (json.side !== undefined) material.side = json.side; + if (json.opacity !== undefined) material.opacity = json.opacity; + if (json.transparent !== undefined) material.transparent = json.transparent; + if (json.alphaTest !== undefined) material.alphaTest = json.alphaTest; + if (json.depthTest !== undefined) material.depthTest = json.depthTest; + if (json.depthWrite !== undefined) material.depthWrite = json.depthWrite; + if (json.colorWrite !== undefined) material.colorWrite = json.colorWrite; + if (json.stencilWrite !== undefined) material.stencilWrite = json.stencilWrite; + if (json.stencilWriteMask !== undefined) material.stencilWriteMask = json.stencilWriteMask; + if (json.stencilFunc !== undefined) material.stencilFunc = json.stencilFunc; + if (json.stencilRef !== undefined) material.stencilRef = json.stencilRef; + if (json.stencilFuncMask !== undefined) material.stencilFuncMask = json.stencilFuncMask; + if (json.stencilFail !== undefined) material.stencilFail = json.stencilFail; + if (json.stencilZFail !== undefined) material.stencilZFail = json.stencilZFail; + if (json.stencilZPass !== undefined) material.stencilZPass = json.stencilZPass; + if (json.wireframe !== undefined) material.wireframe = json.wireframe; + if (json.wireframeLinewidth !== undefined) material.wireframeLinewidth = json.wireframeLinewidth; + if (json.wireframeLinecap !== undefined) material.wireframeLinecap = json.wireframeLinecap; + if (json.wireframeLinejoin !== undefined) material.wireframeLinejoin = json.wireframeLinejoin; + if (json.rotation !== undefined) material.rotation = json.rotation; + if (json.linewidth !== 1) material.linewidth = json.linewidth; + if (json.dashSize !== undefined) material.dashSize = json.dashSize; + if (json.gapSize !== undefined) material.gapSize = json.gapSize; + if (json.scale !== undefined) material.scale = json.scale; + if (json.polygonOffset !== undefined) material.polygonOffset = json.polygonOffset; + if (json.polygonOffsetFactor !== undefined) material.polygonOffsetFactor = json.polygonOffsetFactor; + if (json.polygonOffsetUnits !== undefined) material.polygonOffsetUnits = json.polygonOffsetUnits; + if (json.skinning !== undefined) material.skinning = json.skinning; + if (json.morphTargets !== undefined) material.morphTargets = json.morphTargets; + if (json.morphNormals !== undefined) material.morphNormals = json.morphNormals; + if (json.dithering !== undefined) material.dithering = json.dithering; + if (json.vertexTangents !== undefined) material.vertexTangents = json.vertexTangents; + if (json.visible !== undefined) material.visible = json.visible; + if (json.toneMapped !== undefined) material.toneMapped = json.toneMapped; + if (json.userData !== undefined) material.userData = json.userData; + + if (json.vertexColors !== undefined) { + if (typeof json.vertexColors === 'number') { + material.vertexColors = json.vertexColors > 0 ? true : false; + } else { + material.vertexColors = json.vertexColors; + } + } // Shader Material - counter_textures += 1; - scope.onLoadStart(); + if (json.uniforms !== undefined) { + for (var name in json.uniforms) { + var uniform = json.uniforms[name]; + material.uniforms[name] = {}; - } + switch (uniform.type) { + case 't': + material.uniforms[name].value = getTexture(uniform.value); + break; - } + case 'c': + material.uniforms[name].value = new Color().setHex(uniform.value); + break; - total_textures = counter_textures; + case 'v2': + material.uniforms[name].value = new Vector2().fromArray(uniform.value); + break; - for ( textureID in data.textures ) { + case 'v3': + material.uniforms[name].value = new Vector3().fromArray(uniform.value); + break; - textureJSON = data.textures[ textureID ]; + case 'v4': + material.uniforms[name].value = new Vector4().fromArray(uniform.value); + break; - if ( textureJSON.mapping !== undefined && THREE[ textureJSON.mapping ] !== undefined ) { + case 'm3': + material.uniforms[name].value = new Matrix3().fromArray(uniform.value); + break; - textureJSON.mapping = new THREE[ textureJSON.mapping ](); + case 'm4': + material.uniforms[name].value = new Matrix4().fromArray(uniform.value); + break; + default: + material.uniforms[name].value = uniform.value; + } + } } - if ( textureJSON.url instanceof Array ) { - - var count = textureJSON.url.length; - var url_array = []; - - for( var i = 0; i < count; i ++ ) { - - url_array[ i ] = get_url( textureJSON.url[ i ], data.urlBaseType ); + if (json.defines !== undefined) material.defines = json.defines; + if (json.vertexShader !== undefined) material.vertexShader = json.vertexShader; + if (json.fragmentShader !== undefined) material.fragmentShader = json.fragmentShader; + if (json.extensions !== undefined) { + for (var key in json.extensions) { + material.extensions[key] = json.extensions[key]; } + } // Deprecated - var isCompressed = /\.dds$/i.test( url_array[ 0 ] ); - if ( isCompressed ) { + if (json.shading !== undefined) material.flatShading = json.shading === 1; // THREE.FlatShading + // for PointsMaterial - texture = THREE.ImageUtils.loadCompressedTextureCube( url_array, textureJSON.mapping, generateTextureCallback( count ) ); + if (json.size !== undefined) material.size = json.size; + if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation; // maps - } else { + if (json.map !== undefined) material.map = getTexture(json.map); + if (json.matcap !== undefined) material.matcap = getTexture(json.matcap); + if (json.alphaMap !== undefined) material.alphaMap = getTexture(json.alphaMap); + if (json.bumpMap !== undefined) material.bumpMap = getTexture(json.bumpMap); + if (json.bumpScale !== undefined) material.bumpScale = json.bumpScale; + if (json.normalMap !== undefined) material.normalMap = getTexture(json.normalMap); + if (json.normalMapType !== undefined) material.normalMapType = json.normalMapType; - texture = THREE.ImageUtils.loadTextureCube( url_array, textureJSON.mapping, generateTextureCallback( count ) ); + if (json.normalScale !== undefined) { + var normalScale = json.normalScale; + if (Array.isArray(normalScale) === false) { + // Blender exporter used to export a scalar. See #7459 + normalScale = [normalScale, normalScale]; } - } else { + material.normalScale = new Vector2().fromArray(normalScale); + } + + if (json.displacementMap !== undefined) material.displacementMap = getTexture(json.displacementMap); + if (json.displacementScale !== undefined) material.displacementScale = json.displacementScale; + if (json.displacementBias !== undefined) material.displacementBias = json.displacementBias; + if (json.roughnessMap !== undefined) material.roughnessMap = getTexture(json.roughnessMap); + if (json.metalnessMap !== undefined) material.metalnessMap = getTexture(json.metalnessMap); + if (json.emissiveMap !== undefined) material.emissiveMap = getTexture(json.emissiveMap); + if (json.emissiveIntensity !== undefined) material.emissiveIntensity = json.emissiveIntensity; + if (json.specularMap !== undefined) material.specularMap = getTexture(json.specularMap); + if (json.envMap !== undefined) material.envMap = getTexture(json.envMap); + if (json.envMapIntensity !== undefined) material.envMapIntensity = json.envMapIntensity; + if (json.reflectivity !== undefined) material.reflectivity = json.reflectivity; + if (json.refractionRatio !== undefined) material.refractionRatio = json.refractionRatio; + if (json.lightMap !== undefined) material.lightMap = getTexture(json.lightMap); + if (json.lightMapIntensity !== undefined) material.lightMapIntensity = json.lightMapIntensity; + if (json.aoMap !== undefined) material.aoMap = getTexture(json.aoMap); + if (json.aoMapIntensity !== undefined) material.aoMapIntensity = json.aoMapIntensity; + if (json.gradientMap !== undefined) material.gradientMap = getTexture(json.gradientMap); + if (json.clearcoatMap !== undefined) material.clearcoatMap = getTexture(json.clearcoatMap); + if (json.clearcoatRoughnessMap !== undefined) material.clearcoatRoughnessMap = getTexture(json.clearcoatRoughnessMap); + if (json.clearcoatNormalMap !== undefined) material.clearcoatNormalMap = getTexture(json.clearcoatNormalMap); + if (json.clearcoatNormalScale !== undefined) material.clearcoatNormalScale = new Vector2().fromArray(json.clearcoatNormalScale); + if (json.transmission !== undefined) material.transmission = json.transmission; + if (json.transmissionMap !== undefined) material.transmissionMap = getTexture(json.transmissionMap); + return material; + }, + setTextures: function setTextures(value) { + this.textures = value; + return this; + } + }); - var isCompressed = /\.dds$/i.test( textureJSON.url ); - var fullUrl = get_url( textureJSON.url, data.urlBaseType ); - var textureCallback = generateTextureCallback( 1 ); + var LoaderUtils = { + decodeText: function decodeText(array) { + if (typeof TextDecoder !== 'undefined') { + return new TextDecoder().decode(array); + } // Avoid the String.fromCharCode.apply(null, array) shortcut, which + // throws a "maximum call stack size exceeded" error for large arrays. - if ( isCompressed ) { - texture = THREE.ImageUtils.loadCompressedTexture( fullUrl, textureJSON.mapping, textureCallback ); + var s = ''; - } else { + for (var i = 0, il = array.length; i < il; i++) { + // Implicitly assumes little-endian. + s += String.fromCharCode(array[i]); + } - texture = THREE.ImageUtils.loadTexture( fullUrl, textureJSON.mapping, textureCallback ); + try { + // merges multi-byte utf-8 characters. + return decodeURIComponent(escape(s)); + } catch (e) { + // see #16358 + return s; + } + }, + extractUrlBase: function extractUrlBase(url) { + var index = url.lastIndexOf('/'); + if (index === -1) return './'; + return url.substr(0, index + 1); + } + }; - } + function InstancedBufferGeometry() { + BufferGeometry.call(this); + this.type = 'InstancedBufferGeometry'; + this.instanceCount = Infinity; + } - if ( THREE[ textureJSON.minFilter ] !== undefined ) - texture.minFilter = THREE[ textureJSON.minFilter ]; + InstancedBufferGeometry.prototype = Object.assign(Object.create(BufferGeometry.prototype), { + constructor: InstancedBufferGeometry, + isInstancedBufferGeometry: true, + copy: function copy(source) { + BufferGeometry.prototype.copy.call(this, source); + this.instanceCount = source.instanceCount; + return this; + }, + clone: function clone() { + return new this.constructor().copy(this); + }, + toJSON: function toJSON() { + var data = BufferGeometry.prototype.toJSON.call(this); + data.instanceCount = this.instanceCount; + data.isInstancedBufferGeometry = true; + return data; + } + }); - if ( THREE[ textureJSON.magFilter ] !== undefined ) - texture.magFilter = THREE[ textureJSON.magFilter ]; + function InstancedBufferAttribute(array, itemSize, normalized, meshPerAttribute) { + if (typeof normalized === 'number') { + meshPerAttribute = normalized; + normalized = false; + console.error('THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.'); + } - if ( textureJSON.anisotropy ) texture.anisotropy = textureJSON.anisotropy; + BufferAttribute.call(this, array, itemSize, normalized); + this.meshPerAttribute = meshPerAttribute || 1; + } - if ( textureJSON.repeat ) { + InstancedBufferAttribute.prototype = Object.assign(Object.create(BufferAttribute.prototype), { + constructor: InstancedBufferAttribute, + isInstancedBufferAttribute: true, + copy: function copy(source) { + BufferAttribute.prototype.copy.call(this, source); + this.meshPerAttribute = source.meshPerAttribute; + return this; + }, + toJSON: function toJSON() { + var data = BufferAttribute.prototype.toJSON.call(this); + data.meshPerAttribute = this.meshPerAttribute; + data.isInstancedBufferAttribute = true; + return data; + } + }); - texture.repeat.set( textureJSON.repeat[ 0 ], textureJSON.repeat[ 1 ] ); + function BufferGeometryLoader(manager) { + Loader.call(this, manager); + } - if ( textureJSON.repeat[ 0 ] !== 1 ) texture.wrapS = THREE.RepeatWrapping; - if ( textureJSON.repeat[ 1 ] !== 1 ) texture.wrapT = THREE.RepeatWrapping; + BufferGeometryLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: BufferGeometryLoader, + load: function load(url, onLoad, onProgress, onError) { + var scope = this; + var loader = new FileLoader(scope.manager); + loader.setPath(scope.path); + loader.setRequestHeader(scope.requestHeader); + loader.setWithCredentials(scope.withCredentials); + loader.load(url, function (text) { + try { + onLoad(scope.parse(JSON.parse(text))); + } catch (e) { + if (onError) { + onError(e); + } else { + console.error(e); + } + scope.manager.itemError(url); } + }, onProgress, onError); + }, + parse: function parse(json) { + var interleavedBufferMap = {}; + var arrayBufferMap = {}; - if ( textureJSON.offset ) { + function getInterleavedBuffer(json, uuid) { + if (interleavedBufferMap[uuid] !== undefined) return interleavedBufferMap[uuid]; + var interleavedBuffers = json.interleavedBuffers; + var interleavedBuffer = interleavedBuffers[uuid]; + var buffer = getArrayBuffer(json, interleavedBuffer.buffer); + var array = new TYPED_ARRAYS[interleavedBuffer.type](buffer); + var ib = new InterleavedBuffer(array, interleavedBuffer.stride); + ib.uuid = interleavedBuffer.uuid; + interleavedBufferMap[uuid] = ib; + return ib; + } - texture.offset.set( textureJSON.offset[ 0 ], textureJSON.offset[ 1 ] ); + function getArrayBuffer(json, uuid) { + if (arrayBufferMap[uuid] !== undefined) return arrayBufferMap[uuid]; + var arrayBuffers = json.arrayBuffers; + var arrayBuffer = arrayBuffers[uuid]; + var ab = new Uint32Array(arrayBuffer).buffer; + arrayBufferMap[uuid] = ab; + return ab; + } - } + var geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry(); + var index = json.data.index; - // handle wrap after repeat so that default repeat can be overriden + if (index !== undefined) { + var typedArray = new TYPED_ARRAYS[index.type](index.array); + geometry.setIndex(new BufferAttribute(typedArray, 1)); + } - if ( textureJSON.wrap ) { + var attributes = json.data.attributes; - var wrapMap = { - "repeat": THREE.RepeatWrapping, - "mirror": THREE.MirroredRepeatWrapping - } + for (var key in attributes) { + var attribute = attributes[key]; + var bufferAttribute = void 0; - if ( wrapMap[ textureJSON.wrap[ 0 ] ] !== undefined ) texture.wrapS = wrapMap[ textureJSON.wrap[ 0 ] ]; - if ( wrapMap[ textureJSON.wrap[ 1 ] ] !== undefined ) texture.wrapT = wrapMap[ textureJSON.wrap[ 1 ] ]; + if (attribute.isInterleavedBufferAttribute) { + var interleavedBuffer = getInterleavedBuffer(json.data, attribute.data); + bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized); + } else { + var _typedArray = new TYPED_ARRAYS[attribute.type](attribute.array); + var bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute; + bufferAttribute = new bufferAttributeConstr(_typedArray, attribute.itemSize, attribute.normalized); } + if (attribute.name !== undefined) bufferAttribute.name = attribute.name; + geometry.setAttribute(key, bufferAttribute); } - result.textures[ textureID ] = texture; - - } - - // materials + var morphAttributes = json.data.morphAttributes; - var matID, matJSON; - var parID; + if (morphAttributes) { + for (var _key in morphAttributes) { + var attributeArray = morphAttributes[_key]; + var array = []; - for ( matID in data.materials ) { + for (var i = 0, il = attributeArray.length; i < il; i++) { + var _attribute = attributeArray[i]; - matJSON = data.materials[ matID ]; + var _bufferAttribute = void 0; - for ( parID in matJSON.parameters ) { + if (_attribute.isInterleavedBufferAttribute) { + var _interleavedBuffer = getInterleavedBuffer(json.data, _attribute.data); - if ( parID === "envMap" || parID === "map" || parID === "lightMap" || parID === "bumpMap" ) { - - matJSON.parameters[ parID ] = result.textures[ matJSON.parameters[ parID ] ]; + _bufferAttribute = new InterleavedBufferAttribute(_interleavedBuffer, _attribute.itemSize, _attribute.offset, _attribute.normalized); + } else { + var _typedArray2 = new TYPED_ARRAYS[_attribute.type](_attribute.array); - } else if ( parID === "shading" ) { + _bufferAttribute = new BufferAttribute(_typedArray2, _attribute.itemSize, _attribute.normalized); + } - matJSON.parameters[ parID ] = ( matJSON.parameters[ parID ] === "flat" ) ? THREE.FlatShading : THREE.SmoothShading; + if (_attribute.name !== undefined) _bufferAttribute.name = _attribute.name; + array.push(_bufferAttribute); + } - } else if ( parID === "side" ) { + geometry.morphAttributes[_key] = array; + } + } - if ( matJSON.parameters[ parID ] == "double" ) { + var morphTargetsRelative = json.data.morphTargetsRelative; - matJSON.parameters[ parID ] = THREE.DoubleSide; + if (morphTargetsRelative) { + geometry.morphTargetsRelative = true; + } - } else if ( matJSON.parameters[ parID ] == "back" ) { + var groups = json.data.groups || json.data.drawcalls || json.data.offsets; - matJSON.parameters[ parID ] = THREE.BackSide; + if (groups !== undefined) { + for (var _i = 0, n = groups.length; _i !== n; ++_i) { + var group = groups[_i]; + geometry.addGroup(group.start, group.count, group.materialIndex); + } + } - } else { + var boundingSphere = json.data.boundingSphere; - matJSON.parameters[ parID ] = THREE.FrontSide; + if (boundingSphere !== undefined) { + var center = new Vector3(); - } + if (boundingSphere.center !== undefined) { + center.fromArray(boundingSphere.center); + } - } else if ( parID === "blending" ) { + geometry.boundingSphere = new Sphere(center, boundingSphere.radius); + } + + if (json.name) geometry.name = json.name; + if (json.userData) geometry.userData = json.userData; + return geometry; + } + }); + var TYPED_ARRAYS = { + Int8Array: Int8Array, + Uint8Array: Uint8Array, + // Workaround for IE11 pre KB2929437. See #11440 + Uint8ClampedArray: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : Uint8Array, + Int16Array: Int16Array, + Uint16Array: Uint16Array, + Int32Array: Int32Array, + Uint32Array: Uint32Array, + Float32Array: Float32Array, + Float64Array: Float64Array + }; - matJSON.parameters[ parID ] = matJSON.parameters[ parID ] in THREE ? THREE[ matJSON.parameters[ parID ] ] : THREE.NormalBlending; + var ObjectLoader = /*#__PURE__*/function (_Loader) { + _inheritsLoose(ObjectLoader, _Loader); - } else if ( parID === "combine" ) { + function ObjectLoader(manager) { + return _Loader.call(this, manager) || this; + } - matJSON.parameters[ parID ] = matJSON.parameters[ parID ] in THREE ? THREE[ matJSON.parameters[ parID ] ] : THREE.MultiplyOperation; + var _proto = ObjectLoader.prototype; - } else if ( parID === "vertexColors" ) { + _proto.load = function load(url, onLoad, onProgress, onError) { + var scope = this; + var path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path; + this.resourcePath = this.resourcePath || path; + var loader = new FileLoader(this.manager); + loader.setPath(this.path); + loader.setRequestHeader(this.requestHeader); + loader.setWithCredentials(this.withCredentials); + loader.load(url, function (text) { + var json = null; + + try { + json = JSON.parse(text); + } catch (error) { + if (onError !== undefined) onError(error); + console.error('THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message); + return; + } - if ( matJSON.parameters[ parID ] == "face" ) { + var metadata = json.metadata; - matJSON.parameters[ parID ] = THREE.FaceColors; + if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') { + console.error('THREE.ObjectLoader: Can\'t load ' + url); + return; + } - // default to vertex colors if "vertexColors" is anything else face colors or 0 / null / false + scope.parse(json, onLoad); + }, onProgress, onError); + }; - } else if ( matJSON.parameters[ parID ] ) { + _proto.parse = function parse(json, onLoad) { + var shapes = this.parseShape(json.shapes); + var geometries = this.parseGeometries(json.geometries, shapes); + var images = this.parseImages(json.images, function () { + if (onLoad !== undefined) onLoad(object); + }); + var textures = this.parseTextures(json.textures, images); + var materials = this.parseMaterials(json.materials, textures); + var object = this.parseObject(json.object, geometries, materials); - matJSON.parameters[ parID ] = THREE.VertexColors; + if (json.animations) { + object.animations = this.parseAnimations(json.animations); + } - } + if (json.images === undefined || json.images.length === 0) { + if (onLoad !== undefined) onLoad(object); + } - } else if ( parID === "wrapRGB" ) { + return object; + }; - var v3 = matJSON.parameters[ parID ]; - matJSON.parameters[ parID ] = new THREE.Vector3( v3[ 0 ], v3[ 1 ], v3[ 2 ] ); + _proto.parseShape = function parseShape(json) { + var shapes = {}; + if (json !== undefined) { + for (var i = 0, l = json.length; i < l; i++) { + var shape = new Shape().fromJSON(json[i]); + shapes[shape.uuid] = shape; } - } - if ( matJSON.parameters.opacity !== undefined && matJSON.parameters.opacity < 1.0 ) { - - matJSON.parameters.transparent = true; - - } + return shapes; + }; - if ( matJSON.parameters.normalMap ) { + _proto.parseGeometries = function parseGeometries(json, shapes) { + var geometries = {}; + var geometryShapes; - var shader = THREE.ShaderLib[ "normalmap" ]; - var uniforms = THREE.UniformsUtils.clone( shader.uniforms ); + if (json !== undefined) { + var bufferGeometryLoader = new BufferGeometryLoader(); - var diffuse = matJSON.parameters.color; - var specular = matJSON.parameters.specular; - var ambient = matJSON.parameters.ambient; - var shininess = matJSON.parameters.shininess; + for (var i = 0, l = json.length; i < l; i++) { + var geometry = void 0; + var data = json[i]; - uniforms[ "tNormal" ].value = result.textures[ matJSON.parameters.normalMap ]; + switch (data.type) { + case 'PlaneGeometry': + case 'PlaneBufferGeometry': + geometry = new Geometries[data.type](data.width, data.height, data.widthSegments, data.heightSegments); + break; - if ( matJSON.parameters.normalScale ) { + case 'BoxGeometry': + case 'BoxBufferGeometry': + case 'CubeGeometry': + // backwards compatible + geometry = new Geometries[data.type](data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments); + break; - uniforms[ "uNormalScale" ].value.set( matJSON.parameters.normalScale[ 0 ], matJSON.parameters.normalScale[ 1 ] ); + case 'CircleGeometry': + case 'CircleBufferGeometry': + geometry = new Geometries[data.type](data.radius, data.segments, data.thetaStart, data.thetaLength); + break; - } + case 'CylinderGeometry': + case 'CylinderBufferGeometry': + geometry = new Geometries[data.type](data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); + break; - if ( matJSON.parameters.map ) { + case 'ConeGeometry': + case 'ConeBufferGeometry': + geometry = new Geometries[data.type](data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); + break; - uniforms[ "tDiffuse" ].value = matJSON.parameters.map; - uniforms[ "enableDiffuse" ].value = true; + case 'SphereGeometry': + case 'SphereBufferGeometry': + geometry = new Geometries[data.type](data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength); + break; - } + case 'DodecahedronGeometry': + case 'DodecahedronBufferGeometry': + case 'IcosahedronGeometry': + case 'IcosahedronBufferGeometry': + case 'OctahedronGeometry': + case 'OctahedronBufferGeometry': + case 'TetrahedronGeometry': + case 'TetrahedronBufferGeometry': + geometry = new Geometries[data.type](data.radius, data.detail); + break; - if ( matJSON.parameters.envMap ) { + case 'RingGeometry': + case 'RingBufferGeometry': + geometry = new Geometries[data.type](data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength); + break; - uniforms[ "tCube" ].value = matJSON.parameters.envMap; - uniforms[ "enableReflection" ].value = true; - uniforms[ "reflectivity" ].value = matJSON.parameters.reflectivity; + case 'TorusGeometry': + case 'TorusBufferGeometry': + geometry = new Geometries[data.type](data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc); + break; - } + case 'TorusKnotGeometry': + case 'TorusKnotBufferGeometry': + geometry = new Geometries[data.type](data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q); + break; - if ( matJSON.parameters.lightMap ) { + case 'TubeGeometry': + case 'TubeBufferGeometry': + // This only works for built-in curves (e.g. CatmullRomCurve3). + // User defined curves or instances of CurvePath will not be deserialized. + geometry = new Geometries[data.type](new Curves[data.path.type]().fromJSON(data.path), data.tubularSegments, data.radius, data.radialSegments, data.closed); + break; - uniforms[ "tAO" ].value = matJSON.parameters.lightMap; - uniforms[ "enableAO" ].value = true; + case 'LatheGeometry': + case 'LatheBufferGeometry': + geometry = new Geometries[data.type](data.points, data.segments, data.phiStart, data.phiLength); + break; - } + case 'PolyhedronGeometry': + case 'PolyhedronBufferGeometry': + geometry = new Geometries[data.type](data.vertices, data.indices, data.radius, data.details); + break; - if ( matJSON.parameters.specularMap ) { + case 'ShapeGeometry': + case 'ShapeBufferGeometry': + geometryShapes = []; - uniforms[ "tSpecular" ].value = result.textures[ matJSON.parameters.specularMap ]; - uniforms[ "enableSpecular" ].value = true; + for (var j = 0, jl = data.shapes.length; j < jl; j++) { + var shape = shapes[data.shapes[j]]; + geometryShapes.push(shape); + } - } + geometry = new Geometries[data.type](geometryShapes, data.curveSegments); + break; - if ( matJSON.parameters.displacementMap ) { + case 'ExtrudeGeometry': + case 'ExtrudeBufferGeometry': + geometryShapes = []; - uniforms[ "tDisplacement" ].value = result.textures[ matJSON.parameters.displacementMap ]; - uniforms[ "enableDisplacement" ].value = true; + for (var _j = 0, _jl = data.shapes.length; _j < _jl; _j++) { + var _shape = shapes[data.shapes[_j]]; + geometryShapes.push(_shape); + } - uniforms[ "uDisplacementBias" ].value = matJSON.parameters.displacementBias; - uniforms[ "uDisplacementScale" ].value = matJSON.parameters.displacementScale; + var extrudePath = data.options.extrudePath; - } + if (extrudePath !== undefined) { + data.options.extrudePath = new Curves[extrudePath.type]().fromJSON(extrudePath); + } - uniforms[ "diffuse" ].value.setHex( diffuse ); - uniforms[ "specular" ].value.setHex( specular ); - uniforms[ "ambient" ].value.setHex( ambient ); + geometry = new Geometries[data.type](geometryShapes, data.options); + break; - uniforms[ "shininess" ].value = shininess; + case 'BufferGeometry': + case 'InstancedBufferGeometry': + geometry = bufferGeometryLoader.parse(data); + break; - if ( matJSON.parameters.opacity ) { + case 'Geometry': + console.error('THREE.ObjectLoader: Loading "Geometry" is not supported anymore.'); + break; - uniforms[ "opacity" ].value = matJSON.parameters.opacity; + default: + console.warn('THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"'); + continue; + } + geometry.uuid = data.uuid; + if (data.name !== undefined) geometry.name = data.name; + if (geometry.isBufferGeometry === true && data.userData !== undefined) geometry.userData = data.userData; + geometries[data.uuid] = geometry; } - - var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true }; - - material = new THREE.ShaderMaterial( parameters ); - - } else { - - material = new THREE[ matJSON.type ]( matJSON.parameters ); - } - material.name = matID; + return geometries; + }; - result.materials[ matID ] = material; + _proto.parseMaterials = function parseMaterials(json, textures) { + var cache = {}; // MultiMaterial - } + var materials = {}; - // second pass through all materials to initialize MeshFaceMaterials - // that could be referring to other materials out of order + if (json !== undefined) { + var loader = new MaterialLoader(); + loader.setTextures(textures); - for ( matID in data.materials ) { + for (var i = 0, l = json.length; i < l; i++) { + var data = json[i]; - matJSON = data.materials[ matID ]; + if (data.type === 'MultiMaterial') { + // Deprecated + var array = []; - if ( matJSON.parameters.materials ) { + for (var j = 0; j < data.materials.length; j++) { + var material = data.materials[j]; - var materialArray = []; + if (cache[material.uuid] === undefined) { + cache[material.uuid] = loader.parse(material); + } - for ( var i = 0; i < matJSON.parameters.materials.length; i ++ ) { + array.push(cache[material.uuid]); + } - var label = matJSON.parameters.materials[ i ]; - materialArray.push( result.materials[ label ] ); + materials[data.uuid] = array; + } else { + if (cache[data.uuid] === undefined) { + cache[data.uuid] = loader.parse(data); + } + materials[data.uuid] = cache[data.uuid]; + } } - - result.materials[ matID ].materials = materialArray; - } - } - - // objects ( synchronous init of procedural primitives ) + return materials; + }; - handle_objects(); + _proto.parseAnimations = function parseAnimations(json) { + var animations = []; - // defaults + for (var i = 0; i < json.length; i++) { + var data = json[i]; + var clip = AnimationClip.parse(data); + if (data.uuid !== undefined) clip.uuid = data.uuid; + animations.push(clip); + } - if ( result.cameras && data.defaults.camera ) { + return animations; + }; - result.currentCamera = result.cameras[ data.defaults.camera ]; + _proto.parseImages = function parseImages(json, onLoad) { + var scope = this; + var images = {}; + var loader; + + function loadImage(url) { + scope.manager.itemStart(url); + return loader.load(url, function () { + scope.manager.itemEnd(url); + }, undefined, function () { + scope.manager.itemError(url); + scope.manager.itemEnd(url); + }); + } + + if (json !== undefined && json.length > 0) { + var manager = new LoadingManager(onLoad); + loader = new ImageLoader(manager); + loader.setCrossOrigin(this.crossOrigin); + + for (var i = 0, il = json.length; i < il; i++) { + var image = json[i]; + var url = image.url; + + if (Array.isArray(url)) { + // load array of images e.g CubeTexture + images[image.uuid] = []; + + for (var j = 0, jl = url.length; j < jl; j++) { + var currentUrl = url[j]; + var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(currentUrl) ? currentUrl : scope.resourcePath + currentUrl; + images[image.uuid].push(loadImage(path)); + } + } else { + // load single image + var _path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(image.url) ? image.url : scope.resourcePath + image.url; - } + images[image.uuid] = loadImage(_path); + } + } + } - if ( result.fogs && data.defaults.fog ) { + return images; + }; - result.scene.fog = result.fogs[ data.defaults.fog ]; + _proto.parseTextures = function parseTextures(json, images) { + function parseConstant(value, type) { + if (typeof value === 'number') return value; + console.warn('THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value); + return type[value]; + } - } + var textures = {}; - // synchronous callback + if (json !== undefined) { + for (var i = 0, l = json.length; i < l; i++) { + var data = json[i]; - scope.callbackSync( result ); + if (data.image === undefined) { + console.warn('THREE.ObjectLoader: No "image" specified for', data.uuid); + } - // just in case there are no async elements + if (images[data.image] === undefined) { + console.warn('THREE.ObjectLoader: Undefined image', data.image); + } - async_callback_gate(); + var texture = void 0; - } + if (Array.isArray(images[data.image])) { + texture = new CubeTexture(images[data.image]); + } else { + texture = new Texture(images[data.image]); + } -} + texture.needsUpdate = true; + texture.uuid = data.uuid; + if (data.name !== undefined) texture.name = data.name; + if (data.mapping !== undefined) texture.mapping = parseConstant(data.mapping, TEXTURE_MAPPING); + if (data.offset !== undefined) texture.offset.fromArray(data.offset); + if (data.repeat !== undefined) texture.repeat.fromArray(data.repeat); + if (data.center !== undefined) texture.center.fromArray(data.center); + if (data.rotation !== undefined) texture.rotation = data.rotation; + + if (data.wrap !== undefined) { + texture.wrapS = parseConstant(data.wrap[0], TEXTURE_WRAPPING); + texture.wrapT = parseConstant(data.wrap[1], TEXTURE_WRAPPING); + } -/** - * @author mrdoob / http://mrdoob.com/ - */ + if (data.format !== undefined) texture.format = data.format; + if (data.type !== undefined) texture.type = data.type; + if (data.encoding !== undefined) texture.encoding = data.encoding; + if (data.minFilter !== undefined) texture.minFilter = parseConstant(data.minFilter, TEXTURE_FILTER); + if (data.magFilter !== undefined) texture.magFilter = parseConstant(data.magFilter, TEXTURE_FILTER); + if (data.anisotropy !== undefined) texture.anisotropy = data.anisotropy; + if (data.flipY !== undefined) texture.flipY = data.flipY; + if (data.premultiplyAlpha !== undefined) texture.premultiplyAlpha = data.premultiplyAlpha; + if (data.unpackAlignment !== undefined) texture.unpackAlignment = data.unpackAlignment; + textures[data.uuid] = texture; + } + } -THREE.TextureLoader = function ( manager ) { + return textures; + }; - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + _proto.parseObject = function parseObject(data, geometries, materials) { + var object; -}; + function getGeometry(name) { + if (geometries[name] === undefined) { + console.warn('THREE.ObjectLoader: Undefined geometry', name); + } -THREE.TextureLoader.prototype = { + return geometries[name]; + } - constructor: THREE.TextureLoader, + function getMaterial(name) { + if (name === undefined) return undefined; - load: function ( url, onLoad, onProgress, onError ) { + if (Array.isArray(name)) { + var array = []; - var scope = this; + for (var i = 0, l = name.length; i < l; i++) { + var uuid = name[i]; - var loader = new THREE.ImageLoader( scope.manager ); - loader.setCrossOrigin( this.crossOrigin ); - loader.load( url, function ( image ) { + if (materials[uuid] === undefined) { + console.warn('THREE.ObjectLoader: Undefined material', uuid); + } - var texture = new THREE.Texture( image ); - texture.needsUpdate = true; + array.push(materials[uuid]); + } - if ( onLoad !== undefined ) { + return array; + } - onLoad( texture ); + if (materials[name] === undefined) { + console.warn('THREE.ObjectLoader: Undefined material', name); + } + return materials[name]; } - } ); + var geometry, material; - }, - - setCrossOrigin: function ( value ) { + switch (data.type) { + case 'Scene': + object = new Scene(); - this.crossOrigin = value; + if (data.background !== undefined) { + if (Number.isInteger(data.background)) { + object.background = new Color(data.background); + } + } - } + if (data.fog !== undefined) { + if (data.fog.type === 'Fog') { + object.fog = new Fog(data.fog.color, data.fog.near, data.fog.far); + } else if (data.fog.type === 'FogExp2') { + object.fog = new FogExp2(data.fog.color, data.fog.density); + } + } -}; + break; -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + case 'PerspectiveCamera': + object = new PerspectiveCamera(data.fov, data.aspect, data.near, data.far); + if (data.focus !== undefined) object.focus = data.focus; + if (data.zoom !== undefined) object.zoom = data.zoom; + if (data.filmGauge !== undefined) object.filmGauge = data.filmGauge; + if (data.filmOffset !== undefined) object.filmOffset = data.filmOffset; + if (data.view !== undefined) object.view = Object.assign({}, data.view); + break; -THREE.Material = function () { + case 'OrthographicCamera': + object = new OrthographicCamera(data.left, data.right, data.top, data.bottom, data.near, data.far); + if (data.zoom !== undefined) object.zoom = data.zoom; + if (data.view !== undefined) object.view = Object.assign({}, data.view); + break; - this.id = THREE.MaterialIdCount ++; - this.uuid = THREE.Math.generateUUID(); + case 'AmbientLight': + object = new AmbientLight(data.color, data.intensity); + break; - this.name = ''; - - this.side = THREE.FrontSide; - - this.opacity = 1; - this.transparent = false; - - this.blending = THREE.NormalBlending; - - this.blendSrc = THREE.SrcAlphaFactor; - this.blendDst = THREE.OneMinusSrcAlphaFactor; - this.blendEquation = THREE.AddEquation; + case 'DirectionalLight': + object = new DirectionalLight(data.color, data.intensity); + break; - this.depthTest = true; - this.depthWrite = true; + case 'PointLight': + object = new PointLight(data.color, data.intensity, data.distance, data.decay); + break; - this.polygonOffset = false; - this.polygonOffsetFactor = 0; - this.polygonOffsetUnits = 0; + case 'RectAreaLight': + object = new RectAreaLight(data.color, data.intensity, data.width, data.height); + break; - this.alphaTest = 0; + case 'SpotLight': + object = new SpotLight(data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay); + break; - this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer + case 'HemisphereLight': + object = new HemisphereLight(data.color, data.groundColor, data.intensity); + break; - this.visible = true; + case 'LightProbe': + object = new LightProbe().fromJSON(data); + break; - this.needsUpdate = true; + case 'SkinnedMesh': + console.warn('THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.'); -}; + case 'Mesh': + geometry = getGeometry(data.geometry); + material = getMaterial(data.material); + object = new Mesh(geometry, material); + break; -THREE.Material.prototype = { + case 'InstancedMesh': + geometry = getGeometry(data.geometry); + material = getMaterial(data.material); + var count = data.count; + var instanceMatrix = data.instanceMatrix; + object = new InstancedMesh(geometry, material, count); + object.instanceMatrix = new BufferAttribute(new Float32Array(instanceMatrix.array), 16); + break; - constructor: THREE.Material, + case 'LOD': + object = new LOD(); + break; - setValues: function ( values ) { + case 'Line': + object = new Line(getGeometry(data.geometry), getMaterial(data.material), data.mode); + break; - if ( values === undefined ) return; + case 'LineLoop': + object = new LineLoop(getGeometry(data.geometry), getMaterial(data.material)); + break; - for ( var key in values ) { + case 'LineSegments': + object = new LineSegments(getGeometry(data.geometry), getMaterial(data.material)); + break; - var newValue = values[ key ]; + case 'PointCloud': + case 'Points': + object = new Points(getGeometry(data.geometry), getMaterial(data.material)); + break; - if ( newValue === undefined ) { + case 'Sprite': + object = new Sprite(getMaterial(data.material)); + break; - console.warn( 'THREE.Material: \'' + key + '\' parameter is undefined.' ); - continue; + case 'Group': + object = new Group(); + break; + default: + object = new Object3D(); } - if ( key in this ) { - - var currentValue = this[ key ]; + object.uuid = data.uuid; + if (data.name !== undefined) object.name = data.name; - if ( currentValue instanceof THREE.Color ) { + if (data.matrix !== undefined) { + object.matrix.fromArray(data.matrix); + if (data.matrixAutoUpdate !== undefined) object.matrixAutoUpdate = data.matrixAutoUpdate; + if (object.matrixAutoUpdate) object.matrix.decompose(object.position, object.quaternion, object.scale); + } else { + if (data.position !== undefined) object.position.fromArray(data.position); + if (data.rotation !== undefined) object.rotation.fromArray(data.rotation); + if (data.quaternion !== undefined) object.quaternion.fromArray(data.quaternion); + if (data.scale !== undefined) object.scale.fromArray(data.scale); + } - currentValue.set( newValue ); + if (data.castShadow !== undefined) object.castShadow = data.castShadow; + if (data.receiveShadow !== undefined) object.receiveShadow = data.receiveShadow; - } else if ( currentValue instanceof THREE.Vector3 && newValue instanceof THREE.Vector3 ) { + if (data.shadow) { + if (data.shadow.bias !== undefined) object.shadow.bias = data.shadow.bias; + if (data.shadow.normalBias !== undefined) object.shadow.normalBias = data.shadow.normalBias; + if (data.shadow.radius !== undefined) object.shadow.radius = data.shadow.radius; + if (data.shadow.mapSize !== undefined) object.shadow.mapSize.fromArray(data.shadow.mapSize); + if (data.shadow.camera !== undefined) object.shadow.camera = this.parseObject(data.shadow.camera); + } - currentValue.copy( newValue ); + if (data.visible !== undefined) object.visible = data.visible; + if (data.frustumCulled !== undefined) object.frustumCulled = data.frustumCulled; + if (data.renderOrder !== undefined) object.renderOrder = data.renderOrder; + if (data.userData !== undefined) object.userData = data.userData; + if (data.layers !== undefined) object.layers.mask = data.layers; - } else if ( key == 'overdraw') { + if (data.children !== undefined) { + var children = data.children; - // ensure overdraw is backwards-compatable with legacy boolean type - this[ key ] = Number(newValue); + for (var i = 0; i < children.length; i++) { + object.add(this.parseObject(children[i], geometries, materials)); + } + } - } else { + if (data.type === 'LOD') { + if (data.autoUpdate !== undefined) object.autoUpdate = data.autoUpdate; + var levels = data.levels; - this[ key ] = newValue; + for (var l = 0; l < levels.length; l++) { + var level = levels[l]; + var child = object.getObjectByProperty('uuid', level.object); + if (child !== undefined) { + object.addLevel(child, level.distance); + } } - } + return object; } + /* DEPRECATED */ + ; - }, + _proto.setTexturePath = function setTexturePath(value) { + console.warn('THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().'); + return this.setResourcePath(value); + }; - clone: function ( material ) { + return ObjectLoader; + }(Loader); + + var TEXTURE_MAPPING = { + UVMapping: UVMapping, + CubeReflectionMapping: CubeReflectionMapping, + CubeRefractionMapping: CubeRefractionMapping, + EquirectangularReflectionMapping: EquirectangularReflectionMapping, + EquirectangularRefractionMapping: EquirectangularRefractionMapping, + CubeUVReflectionMapping: CubeUVReflectionMapping, + CubeUVRefractionMapping: CubeUVRefractionMapping + }; + var TEXTURE_WRAPPING = { + RepeatWrapping: RepeatWrapping, + ClampToEdgeWrapping: ClampToEdgeWrapping, + MirroredRepeatWrapping: MirroredRepeatWrapping + }; + var TEXTURE_FILTER = { + NearestFilter: NearestFilter, + NearestMipmapNearestFilter: NearestMipmapNearestFilter, + NearestMipmapLinearFilter: NearestMipmapLinearFilter, + LinearFilter: LinearFilter, + LinearMipmapNearestFilter: LinearMipmapNearestFilter, + LinearMipmapLinearFilter: LinearMipmapLinearFilter + }; - if ( material === undefined ) material = new THREE.Material(); + function ImageBitmapLoader(manager) { + if (typeof createImageBitmap === 'undefined') { + console.warn('THREE.ImageBitmapLoader: createImageBitmap() not supported.'); + } - material.name = this.name; + if (typeof fetch === 'undefined') { + console.warn('THREE.ImageBitmapLoader: fetch() not supported.'); + } - material.side = this.side; + Loader.call(this, manager); + this.options = { + premultiplyAlpha: 'none' + }; + } - material.opacity = this.opacity; - material.transparent = this.transparent; + ImageBitmapLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: ImageBitmapLoader, + isImageBitmapLoader: true, + setOptions: function setOptions(options) { + this.options = options; + return this; + }, + load: function load(url, onLoad, onProgress, onError) { + if (url === undefined) url = ''; + if (this.path !== undefined) url = this.path + url; + url = this.manager.resolveURL(url); + var scope = this; + var cached = Cache.get(url); + + if (cached !== undefined) { + scope.manager.itemStart(url); + setTimeout(function () { + if (onLoad) onLoad(cached); + scope.manager.itemEnd(url); + }, 0); + return cached; + } + + var fetchOptions = {}; + fetchOptions.credentials = this.crossOrigin === 'anonymous' ? 'same-origin' : 'include'; + fetch(url, fetchOptions).then(function (res) { + return res.blob(); + }).then(function (blob) { + return createImageBitmap(blob, scope.options); + }).then(function (imageBitmap) { + Cache.add(url, imageBitmap); + if (onLoad) onLoad(imageBitmap); + scope.manager.itemEnd(url); + }).catch(function (e) { + if (onError) onError(e); + scope.manager.itemError(url); + scope.manager.itemEnd(url); + }); + scope.manager.itemStart(url); + } + }); - material.blending = this.blending; + function ShapePath() { + this.type = 'ShapePath'; + this.color = new Color(); + this.subPaths = []; + this.currentPath = null; + } - material.blendSrc = this.blendSrc; - material.blendDst = this.blendDst; - material.blendEquation = this.blendEquation; + Object.assign(ShapePath.prototype, { + moveTo: function moveTo(x, y) { + this.currentPath = new Path(); + this.subPaths.push(this.currentPath); + this.currentPath.moveTo(x, y); + return this; + }, + lineTo: function lineTo(x, y) { + this.currentPath.lineTo(x, y); + return this; + }, + quadraticCurveTo: function quadraticCurveTo(aCPx, aCPy, aX, aY) { + this.currentPath.quadraticCurveTo(aCPx, aCPy, aX, aY); + return this; + }, + bezierCurveTo: function bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { + this.currentPath.bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY); + return this; + }, + splineThru: function splineThru(pts) { + this.currentPath.splineThru(pts); + return this; + }, + toShapes: function toShapes(isCCW, noHoles) { + function toShapesNoHoles(inSubpaths) { + var shapes = []; - material.depthTest = this.depthTest; - material.depthWrite = this.depthWrite; + for (var i = 0, l = inSubpaths.length; i < l; i++) { + var _tmpPath = inSubpaths[i]; - material.polygonOffset = this.polygonOffset; - material.polygonOffsetFactor = this.polygonOffsetFactor; - material.polygonOffsetUnits = this.polygonOffsetUnits; + var _tmpShape = new Shape(); - material.alphaTest = this.alphaTest; + _tmpShape.curves = _tmpPath.curves; + shapes.push(_tmpShape); + } - material.overdraw = this.overdraw; + return shapes; + } - material.visible = this.visible; + function isPointInsidePolygon(inPt, inPolygon) { + var polyLen = inPolygon.length; // inPt on polygon contour => immediate success or + // toggling of inside/outside at every single! intersection point of an edge + // with the horizontal line through inPt, left of inPt + // not counting lowerY endpoints of edges and whole edges on that line - return material; + var inside = false; - }, + for (var p = polyLen - 1, q = 0; q < polyLen; p = q++) { + var edgeLowPt = inPolygon[p]; + var edgeHighPt = inPolygon[q]; + var edgeDx = edgeHighPt.x - edgeLowPt.x; + var edgeDy = edgeHighPt.y - edgeLowPt.y; - dispose: function () { + if (Math.abs(edgeDy) > Number.EPSILON) { + // not parallel + if (edgeDy < 0) { + edgeLowPt = inPolygon[q]; + edgeDx = -edgeDx; + edgeHighPt = inPolygon[p]; + edgeDy = -edgeDy; + } - this.dispatchEvent( { type: 'dispose' } ); + if (inPt.y < edgeLowPt.y || inPt.y > edgeHighPt.y) continue; - } + if (inPt.y === edgeLowPt.y) { + if (inPt.x === edgeLowPt.x) return true; // inPt is on contour ? + // continue; // no intersection or edgeLowPt => doesn't count !!! + } else { + var perpEdge = edgeDy * (inPt.x - edgeLowPt.x) - edgeDx * (inPt.y - edgeLowPt.y); + if (perpEdge === 0) return true; // inPt is on contour ? -}; + if (perpEdge < 0) continue; + inside = !inside; // true intersection left of inPt + } + } else { + // parallel or collinear + if (inPt.y !== edgeLowPt.y) continue; // parallel + // edge lies on the same horizontal line as inPt -THREE.EventDispatcher.prototype.apply( THREE.Material.prototype ); + if (edgeHighPt.x <= inPt.x && inPt.x <= edgeLowPt.x || edgeLowPt.x <= inPt.x && inPt.x <= edgeHighPt.x) return true; // inPt: Point on contour ! + // continue; + } + } -THREE.MaterialIdCount = 0; + return inside; + } -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * linewidth: , - * linecap: "round", - * linejoin: "round", - * - * vertexColors: - * - * fog: - * } - */ + var isClockWise = ShapeUtils.isClockWise; + var subPaths = this.subPaths; + if (subPaths.length === 0) return []; + if (noHoles === true) return toShapesNoHoles(subPaths); + var solid, tmpPath, tmpShape; + var shapes = []; -THREE.LineBasicMaterial = function ( parameters ) { + if (subPaths.length === 1) { + tmpPath = subPaths[0]; + tmpShape = new Shape(); + tmpShape.curves = tmpPath.curves; + shapes.push(tmpShape); + return shapes; + } - THREE.Material.call( this ); + var holesFirst = !isClockWise(subPaths[0].getPoints()); + holesFirst = isCCW ? !holesFirst : holesFirst; // console.log("Holes first", holesFirst); - this.color = new THREE.Color( 0xffffff ); + var betterShapeHoles = []; + var newShapes = []; + var newShapeHoles = []; + var mainIdx = 0; + var tmpPoints; + newShapes[mainIdx] = undefined; + newShapeHoles[mainIdx] = []; - this.linewidth = 1; - this.linecap = 'round'; - this.linejoin = 'round'; + for (var i = 0, l = subPaths.length; i < l; i++) { + tmpPath = subPaths[i]; + tmpPoints = tmpPath.getPoints(); + solid = isClockWise(tmpPoints); + solid = isCCW ? !solid : solid; + + if (solid) { + if (!holesFirst && newShapes[mainIdx]) mainIdx++; + newShapes[mainIdx] = { + s: new Shape(), + p: tmpPoints + }; + newShapes[mainIdx].s.curves = tmpPath.curves; + if (holesFirst) mainIdx++; + newShapeHoles[mainIdx] = []; //console.log('cw', i); + } else { + newShapeHoles[mainIdx].push({ + h: tmpPath, + p: tmpPoints[0] + }); //console.log('ccw', i); + } + } // only Holes? -> probably all Shapes with wrong orientation - this.vertexColors = false; - this.fog = true; + if (!newShapes[0]) return toShapesNoHoles(subPaths); - this.setValues( parameters ); + if (newShapes.length > 1) { + var ambiguous = false; + var toChange = []; -}; + for (var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { + betterShapeHoles[sIdx] = []; + } -THREE.LineBasicMaterial.prototype = Object.create( THREE.Material.prototype ); + for (var _sIdx = 0, _sLen = newShapes.length; _sIdx < _sLen; _sIdx++) { + var sho = newShapeHoles[_sIdx]; -THREE.LineBasicMaterial.prototype.clone = function () { + for (var hIdx = 0; hIdx < sho.length; hIdx++) { + var ho = sho[hIdx]; + var hole_unassigned = true; - var material = new THREE.LineBasicMaterial(); + for (var s2Idx = 0; s2Idx < newShapes.length; s2Idx++) { + if (isPointInsidePolygon(ho.p, newShapes[s2Idx].p)) { + if (_sIdx !== s2Idx) toChange.push({ + froms: _sIdx, + tos: s2Idx, + hole: hIdx + }); - THREE.Material.prototype.clone.call( this, material ); + if (hole_unassigned) { + hole_unassigned = false; + betterShapeHoles[s2Idx].push(ho); + } else { + ambiguous = true; + } + } + } - material.color.copy( this.color ); + if (hole_unassigned) { + betterShapeHoles[_sIdx].push(ho); + } + } + } // console.log("ambiguous: ", ambiguous); - material.linewidth = this.linewidth; - material.linecap = this.linecap; - material.linejoin = this.linejoin; - material.vertexColors = this.vertexColors; + if (toChange.length > 0) { + // console.log("to change: ", toChange); + if (!ambiguous) newShapeHoles = betterShapeHoles; + } + } - material.fog = this.fog; + var tmpHoles; - return material; + for (var _i = 0, il = newShapes.length; _i < il; _i++) { + tmpShape = newShapes[_i].s; + shapes.push(tmpShape); + tmpHoles = newShapeHoles[_i]; -}; + for (var j = 0, jl = tmpHoles.length; j < jl; j++) { + tmpShape.holes.push(tmpHoles[j].h); + } + } //console.log("shape", shapes); -/** - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * linewidth: , - * - * scale: , - * dashSize: , - * gapSize: , - * - * vertexColors: - * - * fog: - * } - */ -THREE.LineDashedMaterial = function ( parameters ) { + return shapes; + } + }); - THREE.Material.call( this ); + function Font(data) { + this.type = 'Font'; + this.data = data; + } - this.color = new THREE.Color( 0xffffff ); + Object.assign(Font.prototype, { + isFont: true, + generateShapes: function generateShapes(text, size) { + if (size === undefined) size = 100; + var shapes = []; + var paths = createPaths(text, size, this.data); - this.linewidth = 1; + for (var p = 0, pl = paths.length; p < pl; p++) { + Array.prototype.push.apply(shapes, paths[p].toShapes()); + } - this.scale = 1; - this.dashSize = 3; - this.gapSize = 1; + return shapes; + } + }); - this.vertexColors = false; + function createPaths(text, size, data) { + var chars = Array.from ? Array.from(text) : String(text).split(''); // workaround for IE11, see #13988 - this.fog = true; + var scale = size / data.resolution; + var line_height = (data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness) * scale; + var paths = []; + var offsetX = 0, + offsetY = 0; - this.setValues( parameters ); + for (var i = 0; i < chars.length; i++) { + var char = chars[i]; -}; + if (char === '\n') { + offsetX = 0; + offsetY -= line_height; + } else { + var ret = createPath(char, scale, offsetX, offsetY, data); + offsetX += ret.offsetX; + paths.push(ret.path); + } + } -THREE.LineDashedMaterial.prototype = Object.create( THREE.Material.prototype ); + return paths; + } -THREE.LineDashedMaterial.prototype.clone = function () { + function createPath(char, scale, offsetX, offsetY, data) { + var glyph = data.glyphs[char] || data.glyphs['?']; - var material = new THREE.LineDashedMaterial(); + if (!glyph) { + console.error('THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.'); + return; + } - THREE.Material.prototype.clone.call( this, material ); + var path = new ShapePath(); + var x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2; - material.color.copy( this.color ); + if (glyph.o) { + var outline = glyph._cachedOutline || (glyph._cachedOutline = glyph.o.split(' ')); - material.linewidth = this.linewidth; + for (var i = 0, l = outline.length; i < l;) { + var action = outline[i++]; - material.scale = this.scale; - material.dashSize = this.dashSize; - material.gapSize = this.gapSize; + switch (action) { + case 'm': + // moveTo + x = outline[i++] * scale + offsetX; + y = outline[i++] * scale + offsetY; + path.moveTo(x, y); + break; - material.vertexColors = this.vertexColors; + case 'l': + // lineTo + x = outline[i++] * scale + offsetX; + y = outline[i++] * scale + offsetY; + path.lineTo(x, y); + break; - material.fog = this.fog; + case 'q': + // quadraticCurveTo + cpx = outline[i++] * scale + offsetX; + cpy = outline[i++] * scale + offsetY; + cpx1 = outline[i++] * scale + offsetX; + cpy1 = outline[i++] * scale + offsetY; + path.quadraticCurveTo(cpx1, cpy1, cpx, cpy); + break; - return material; + case 'b': + // bezierCurveTo + cpx = outline[i++] * scale + offsetX; + cpy = outline[i++] * scale + offsetY; + cpx1 = outline[i++] * scale + offsetX; + cpy1 = outline[i++] * scale + offsetY; + cpx2 = outline[i++] * scale + offsetX; + cpy2 = outline[i++] * scale + offsetY; + path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, cpx, cpy); + break; + } + } + } -}; + return { + offsetX: glyph.ha * scale, + path: path + }; + } -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * map: new THREE.Texture( ), - * - * lightMap: new THREE.Texture( ), - * - * specularMap: new THREE.Texture( ), - * - * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ), - * combine: THREE.Multiply, - * reflectivity: , - * refractionRatio: , - * - * shading: THREE.SmoothShading, - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * wireframe: , - * wireframeLinewidth: , - * - * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, - * - * skinning: , - * morphTargets: , - * - * fog: - * } - */ + function FontLoader(manager) { + Loader.call(this, manager); + } -THREE.MeshBasicMaterial = function ( parameters ) { + FontLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: FontLoader, + load: function load(url, onLoad, onProgress, onError) { + var scope = this; + var loader = new FileLoader(this.manager); + loader.setPath(this.path); + loader.setRequestHeader(this.requestHeader); + loader.setWithCredentials(scope.withCredentials); + loader.load(url, function (text) { + var json; + + try { + json = JSON.parse(text); + } catch (e) { + console.warn('THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.'); + json = JSON.parse(text.substring(65, text.length - 2)); + } - THREE.Material.call( this ); + var font = scope.parse(json); + if (onLoad) onLoad(font); + }, onProgress, onError); + }, + parse: function parse(json) { + return new Font(json); + } + }); - this.color = new THREE.Color( 0xffffff ); // emissive + var _context; - this.map = null; + var AudioContext = { + getContext: function getContext() { + if (_context === undefined) { + _context = new (window.AudioContext || window.webkitAudioContext)(); + } - this.lightMap = null; + return _context; + }, + setContext: function setContext(value) { + _context = value; + } + }; - this.specularMap = null; + function AudioLoader(manager) { + Loader.call(this, manager); + } - this.envMap = null; - this.combine = THREE.MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; + AudioLoader.prototype = Object.assign(Object.create(Loader.prototype), { + constructor: AudioLoader, + load: function load(url, onLoad, onProgress, onError) { + var scope = this; + var loader = new FileLoader(scope.manager); + loader.setResponseType('arraybuffer'); + loader.setPath(scope.path); + loader.setRequestHeader(scope.requestHeader); + loader.setWithCredentials(scope.withCredentials); + loader.load(url, function (buffer) { + try { + // Create a copy of the buffer. The `decodeAudioData` method + // detaches the buffer when complete, preventing reuse. + var bufferCopy = buffer.slice(0); + var context = AudioContext.getContext(); + context.decodeAudioData(bufferCopy, function (audioBuffer) { + onLoad(audioBuffer); + }); + } catch (e) { + if (onError) { + onError(e); + } else { + console.error(e); + } - this.fog = true; + scope.manager.itemError(url); + } + }, onProgress, onError); + } + }); - this.shading = THREE.SmoothShading; + function HemisphereLightProbe(skyColor, groundColor, intensity) { + LightProbe.call(this, undefined, intensity); + var color1 = new Color().set(skyColor); + var color2 = new Color().set(groundColor); + var sky = new Vector3(color1.r, color1.g, color1.b); + var ground = new Vector3(color2.r, color2.g, color2.b); // without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI ); - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; + var c0 = Math.sqrt(Math.PI); + var c1 = c0 * Math.sqrt(0.75); + this.sh.coefficients[0].copy(sky).add(ground).multiplyScalar(c0); + this.sh.coefficients[1].copy(sky).sub(ground).multiplyScalar(c1); + } - this.vertexColors = THREE.NoColors; + HemisphereLightProbe.prototype = Object.assign(Object.create(LightProbe.prototype), { + constructor: HemisphereLightProbe, + isHemisphereLightProbe: true, + copy: function copy(source) { + // modifying colors not currently supported + LightProbe.prototype.copy.call(this, source); + return this; + }, + toJSON: function toJSON(meta) { + var data = LightProbe.prototype.toJSON.call(this, meta); // data.sh = this.sh.toArray(); // todo - this.skinning = false; - this.morphTargets = false; + return data; + } + }); - this.setValues( parameters ); + function AmbientLightProbe(color, intensity) { + LightProbe.call(this, undefined, intensity); + var color1 = new Color().set(color); // without extra factor of PI in the shader, would be 2 / Math.sqrt( Math.PI ); -}; + this.sh.coefficients[0].set(color1.r, color1.g, color1.b).multiplyScalar(2 * Math.sqrt(Math.PI)); + } -THREE.MeshBasicMaterial.prototype = Object.create( THREE.Material.prototype ); + AmbientLightProbe.prototype = Object.assign(Object.create(LightProbe.prototype), { + constructor: AmbientLightProbe, + isAmbientLightProbe: true, + copy: function copy(source) { + // modifying color not currently supported + LightProbe.prototype.copy.call(this, source); + return this; + }, + toJSON: function toJSON(meta) { + var data = LightProbe.prototype.toJSON.call(this, meta); // data.sh = this.sh.toArray(); // todo + + return data; + } + }); + + var _eyeRight = new Matrix4(); + + var _eyeLeft = new Matrix4(); + + function StereoCamera() { + this.type = 'StereoCamera'; + this.aspect = 1; + this.eyeSep = 0.064; + this.cameraL = new PerspectiveCamera(); + this.cameraL.layers.enable(1); + this.cameraL.matrixAutoUpdate = false; + this.cameraR = new PerspectiveCamera(); + this.cameraR.layers.enable(2); + this.cameraR.matrixAutoUpdate = false; + this._cache = { + focus: null, + fov: null, + aspect: null, + near: null, + far: null, + zoom: null, + eyeSep: null + }; + } -THREE.MeshBasicMaterial.prototype.clone = function () { + Object.assign(StereoCamera.prototype, { + update: function update(camera) { + var cache = this._cache; + var needsUpdate = cache.focus !== camera.focus || cache.fov !== camera.fov || cache.aspect !== camera.aspect * this.aspect || cache.near !== camera.near || cache.far !== camera.far || cache.zoom !== camera.zoom || cache.eyeSep !== this.eyeSep; - var material = new THREE.MeshBasicMaterial(); + if (needsUpdate) { + cache.focus = camera.focus; + cache.fov = camera.fov; + cache.aspect = camera.aspect * this.aspect; + cache.near = camera.near; + cache.far = camera.far; + cache.zoom = camera.zoom; + cache.eyeSep = this.eyeSep; // Off-axis stereoscopic effect based on + // http://paulbourke.net/stereographics/stereorender/ - THREE.Material.prototype.clone.call( this, material ); + var projectionMatrix = camera.projectionMatrix.clone(); + var eyeSepHalf = cache.eyeSep / 2; + var eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus; + var ymax = cache.near * Math.tan(MathUtils.DEG2RAD * cache.fov * 0.5) / cache.zoom; + var xmin, xmax; // translate xOffset - material.color.copy( this.color ); + _eyeLeft.elements[12] = -eyeSepHalf; + _eyeRight.elements[12] = eyeSepHalf; // for left eye - material.map = this.map; + xmin = -ymax * cache.aspect + eyeSepOnProjection; + xmax = ymax * cache.aspect + eyeSepOnProjection; + projectionMatrix.elements[0] = 2 * cache.near / (xmax - xmin); + projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin); + this.cameraL.projectionMatrix.copy(projectionMatrix); // for right eye - material.lightMap = this.lightMap; + xmin = -ymax * cache.aspect - eyeSepOnProjection; + xmax = ymax * cache.aspect - eyeSepOnProjection; + projectionMatrix.elements[0] = 2 * cache.near / (xmax - xmin); + projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin); + this.cameraR.projectionMatrix.copy(projectionMatrix); + } - material.specularMap = this.specularMap; + this.cameraL.matrixWorld.copy(camera.matrixWorld).multiply(_eyeLeft); + this.cameraR.matrixWorld.copy(camera.matrixWorld).multiply(_eyeRight); + } + }); - material.envMap = this.envMap; - material.combine = this.combine; - material.reflectivity = this.reflectivity; - material.refractionRatio = this.refractionRatio; + var Clock = /*#__PURE__*/function () { + function Clock(autoStart) { + this.autoStart = autoStart !== undefined ? autoStart : true; + this.startTime = 0; + this.oldTime = 0; + this.elapsedTime = 0; + this.running = false; + } - material.fog = this.fog; + var _proto = Clock.prototype; - material.shading = this.shading; + _proto.start = function start() { + this.startTime = (typeof performance === 'undefined' ? Date : performance).now(); // see #10732 - material.wireframe = this.wireframe; - material.wireframeLinewidth = this.wireframeLinewidth; - material.wireframeLinecap = this.wireframeLinecap; - material.wireframeLinejoin = this.wireframeLinejoin; + this.oldTime = this.startTime; + this.elapsedTime = 0; + this.running = true; + }; - material.vertexColors = this.vertexColors; + _proto.stop = function stop() { + this.getElapsedTime(); + this.running = false; + this.autoStart = false; + }; - material.skinning = this.skinning; - material.morphTargets = this.morphTargets; + _proto.getElapsedTime = function getElapsedTime() { + this.getDelta(); + return this.elapsedTime; + }; - return material; + _proto.getDelta = function getDelta() { + var diff = 0; -}; + if (this.autoStart && !this.running) { + this.start(); + return 0; + } -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * ambient: , - * emissive: , - * opacity: , - * - * map: new THREE.Texture( ), - * - * lightMap: new THREE.Texture( ), - * - * specularMap: new THREE.Texture( ), - * - * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ), - * combine: THREE.Multiply, - * reflectivity: , - * refractionRatio: , - * - * shading: THREE.SmoothShading, - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * wireframe: , - * wireframeLinewidth: , - * - * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, - * - * skinning: , - * morphTargets: , - * morphNormals: , - * - * fog: - * } - */ + if (this.running) { + var newTime = (typeof performance === 'undefined' ? Date : performance).now(); + diff = (newTime - this.oldTime) / 1000; + this.oldTime = newTime; + this.elapsedTime += diff; + } -THREE.MeshLambertMaterial = function ( parameters ) { + return diff; + }; - THREE.Material.call( this ); + return Clock; + }(); - this.color = new THREE.Color( 0xffffff ); // diffuse - this.ambient = new THREE.Color( 0xffffff ); - this.emissive = new THREE.Color( 0x000000 ); + var _position$2 = /*@__PURE__*/new Vector3(); - this.wrapAround = false; - this.wrapRGB = new THREE.Vector3( 1, 1, 1 ); + var _quaternion$3 = /*@__PURE__*/new Quaternion(); - this.map = null; + var _scale$1 = /*@__PURE__*/new Vector3(); - this.lightMap = null; + var _orientation = /*@__PURE__*/new Vector3(); - this.specularMap = null; + var AudioListener = /*#__PURE__*/function (_Object3D) { + _inheritsLoose(AudioListener, _Object3D); - this.envMap = null; - this.combine = THREE.MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; + function AudioListener() { + var _this; - this.fog = true; - - this.shading = THREE.SmoothShading; - - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; - - this.vertexColors = THREE.NoColors; - - this.skinning = false; - this.morphTargets = false; - this.morphNormals = false; - - this.setValues( parameters ); - -}; - -THREE.MeshLambertMaterial.prototype = Object.create( THREE.Material.prototype ); - -THREE.MeshLambertMaterial.prototype.clone = function () { - - var material = new THREE.MeshLambertMaterial(); - - THREE.Material.prototype.clone.call( this, material ); - - material.color.copy( this.color ); - material.ambient.copy( this.ambient ); - material.emissive.copy( this.emissive ); - - material.wrapAround = this.wrapAround; - material.wrapRGB.copy( this.wrapRGB ); - - material.map = this.map; - - material.lightMap = this.lightMap; - - material.specularMap = this.specularMap; - - material.envMap = this.envMap; - material.combine = this.combine; - material.reflectivity = this.reflectivity; - material.refractionRatio = this.refractionRatio; - - material.fog = this.fog; - - material.shading = this.shading; - - material.wireframe = this.wireframe; - material.wireframeLinewidth = this.wireframeLinewidth; - material.wireframeLinecap = this.wireframeLinecap; - material.wireframeLinejoin = this.wireframeLinejoin; - - material.vertexColors = this.vertexColors; - - material.skinning = this.skinning; - material.morphTargets = this.morphTargets; - material.morphNormals = this.morphNormals; + _this = _Object3D.call(this) || this; + _this.type = 'AudioListener'; + _this.context = AudioContext.getContext(); + _this.gain = _this.context.createGain(); - return material; + _this.gain.connect(_this.context.destination); -}; + _this.filter = null; + _this.timeDelta = 0; // private -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * ambient: , - * emissive: , - * specular: , - * shininess: , - * opacity: , - * - * map: new THREE.Texture( ), - * - * lightMap: new THREE.Texture( ), - * - * bumpMap: new THREE.Texture( ), - * bumpScale: , - * - * normalMap: new THREE.Texture( ), - * normalScale: , - * - * specularMap: new THREE.Texture( ), - * - * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ), - * combine: THREE.Multiply, - * reflectivity: , - * refractionRatio: , - * - * shading: THREE.SmoothShading, - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * wireframe: , - * wireframeLinewidth: , - * - * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, - * - * skinning: , - * morphTargets: , - * morphNormals: , - * - * fog: - * } - */ + _this._clock = new Clock(); + return _this; + } -THREE.MeshPhongMaterial = function ( parameters ) { + var _proto = AudioListener.prototype; - THREE.Material.call( this ); + _proto.getInput = function getInput() { + return this.gain; + }; - this.color = new THREE.Color( 0xffffff ); // diffuse - this.ambient = new THREE.Color( 0xffffff ); - this.emissive = new THREE.Color( 0x000000 ); - this.specular = new THREE.Color( 0x111111 ); - this.shininess = 30; + _proto.removeFilter = function removeFilter() { + if (this.filter !== null) { + this.gain.disconnect(this.filter); + this.filter.disconnect(this.context.destination); + this.gain.connect(this.context.destination); + this.filter = null; + } - this.metal = false; + return this; + }; - this.wrapAround = false; - this.wrapRGB = new THREE.Vector3( 1, 1, 1 ); + _proto.getFilter = function getFilter() { + return this.filter; + }; - this.map = null; + _proto.setFilter = function setFilter(value) { + if (this.filter !== null) { + this.gain.disconnect(this.filter); + this.filter.disconnect(this.context.destination); + } else { + this.gain.disconnect(this.context.destination); + } - this.lightMap = null; + this.filter = value; + this.gain.connect(this.filter); + this.filter.connect(this.context.destination); + return this; + }; - this.bumpMap = null; - this.bumpScale = 1; + _proto.getMasterVolume = function getMasterVolume() { + return this.gain.gain.value; + }; - this.normalMap = null; - this.normalScale = new THREE.Vector2( 1, 1 ); + _proto.setMasterVolume = function setMasterVolume(value) { + this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01); + return this; + }; - this.specularMap = null; + _proto.updateMatrixWorld = function updateMatrixWorld(force) { + _Object3D.prototype.updateMatrixWorld.call(this, force); + + var listener = this.context.listener; + var up = this.up; + this.timeDelta = this._clock.getDelta(); + this.matrixWorld.decompose(_position$2, _quaternion$3, _scale$1); + + _orientation.set(0, 0, -1).applyQuaternion(_quaternion$3); + + if (listener.positionX) { + // code path for Chrome (see #14393) + var endTime = this.context.currentTime + this.timeDelta; + listener.positionX.linearRampToValueAtTime(_position$2.x, endTime); + listener.positionY.linearRampToValueAtTime(_position$2.y, endTime); + listener.positionZ.linearRampToValueAtTime(_position$2.z, endTime); + listener.forwardX.linearRampToValueAtTime(_orientation.x, endTime); + listener.forwardY.linearRampToValueAtTime(_orientation.y, endTime); + listener.forwardZ.linearRampToValueAtTime(_orientation.z, endTime); + listener.upX.linearRampToValueAtTime(up.x, endTime); + listener.upY.linearRampToValueAtTime(up.y, endTime); + listener.upZ.linearRampToValueAtTime(up.z, endTime); + } else { + listener.setPosition(_position$2.x, _position$2.y, _position$2.z); + listener.setOrientation(_orientation.x, _orientation.y, _orientation.z, up.x, up.y, up.z); + } + }; - this.envMap = null; - this.combine = THREE.MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; + return AudioListener; + }(Object3D); + + var Audio = /*#__PURE__*/function (_Object3D) { + _inheritsLoose(Audio, _Object3D); + + function Audio(listener) { + var _this; + + _this = _Object3D.call(this) || this; + _this.type = 'Audio'; + _this.listener = listener; + _this.context = listener.context; + _this.gain = _this.context.createGain(); + + _this.gain.connect(listener.getInput()); + + _this.autoplay = false; + _this.buffer = null; + _this.detune = 0; + _this.loop = false; + _this.loopStart = 0; + _this.loopEnd = 0; + _this.offset = 0; + _this.duration = undefined; + _this.playbackRate = 1; + _this.isPlaying = false; + _this.hasPlaybackControl = true; + _this.source = null; + _this.sourceType = 'empty'; + _this._startedAt = 0; + _this._progress = 0; + _this._connected = false; + _this.filters = []; + return _this; + } + + var _proto = Audio.prototype; + + _proto.getOutput = function getOutput() { + return this.gain; + }; - this.fog = true; + _proto.setNodeSource = function setNodeSource(audioNode) { + this.hasPlaybackControl = false; + this.sourceType = 'audioNode'; + this.source = audioNode; + this.connect(); + return this; + }; - this.shading = THREE.SmoothShading; + _proto.setMediaElementSource = function setMediaElementSource(mediaElement) { + this.hasPlaybackControl = false; + this.sourceType = 'mediaNode'; + this.source = this.context.createMediaElementSource(mediaElement); + this.connect(); + return this; + }; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; + _proto.setMediaStreamSource = function setMediaStreamSource(mediaStream) { + this.hasPlaybackControl = false; + this.sourceType = 'mediaStreamNode'; + this.source = this.context.createMediaStreamSource(mediaStream); + this.connect(); + return this; + }; - this.vertexColors = THREE.NoColors; + _proto.setBuffer = function setBuffer(audioBuffer) { + this.buffer = audioBuffer; + this.sourceType = 'buffer'; + if (this.autoplay) this.play(); + return this; + }; - this.skinning = false; - this.morphTargets = false; - this.morphNormals = false; + _proto.play = function play(delay) { + if (delay === undefined) delay = 0; - this.setValues( parameters ); + if (this.isPlaying === true) { + console.warn('THREE.Audio: Audio is already playing.'); + return; + } -}; + if (this.hasPlaybackControl === false) { + console.warn('THREE.Audio: this Audio has no playback control.'); + return; + } -THREE.MeshPhongMaterial.prototype = Object.create( THREE.Material.prototype ); + this._startedAt = this.context.currentTime + delay; + var source = this.context.createBufferSource(); + source.buffer = this.buffer; + source.loop = this.loop; + source.loopStart = this.loopStart; + source.loopEnd = this.loopEnd; + source.onended = this.onEnded.bind(this); + source.start(this._startedAt, this._progress + this.offset, this.duration); + this.isPlaying = true; + this.source = source; + this.setDetune(this.detune); + this.setPlaybackRate(this.playbackRate); + return this.connect(); + }; -THREE.MeshPhongMaterial.prototype.clone = function () { + _proto.pause = function pause() { + if (this.hasPlaybackControl === false) { + console.warn('THREE.Audio: this Audio has no playback control.'); + return; + } - var material = new THREE.MeshPhongMaterial(); + if (this.isPlaying === true) { + // update current progress + this._progress += Math.max(this.context.currentTime - this._startedAt, 0) * this.playbackRate; - THREE.Material.prototype.clone.call( this, material ); + if (this.loop === true) { + // ensure _progress does not exceed duration with looped audios + this._progress = this._progress % (this.duration || this.buffer.duration); + } - material.color.copy( this.color ); - material.ambient.copy( this.ambient ); - material.emissive.copy( this.emissive ); - material.specular.copy( this.specular ); - material.shininess = this.shininess; + this.source.stop(); + this.source.onended = null; + this.isPlaying = false; + } - material.metal = this.metal; + return this; + }; - material.wrapAround = this.wrapAround; - material.wrapRGB.copy( this.wrapRGB ); + _proto.stop = function stop() { + if (this.hasPlaybackControl === false) { + console.warn('THREE.Audio: this Audio has no playback control.'); + return; + } - material.map = this.map; + this._progress = 0; + this.source.stop(); + this.source.onended = null; + this.isPlaying = false; + return this; + }; - material.lightMap = this.lightMap; + _proto.connect = function connect() { + if (this.filters.length > 0) { + this.source.connect(this.filters[0]); - material.bumpMap = this.bumpMap; - material.bumpScale = this.bumpScale; + for (var i = 1, l = this.filters.length; i < l; i++) { + this.filters[i - 1].connect(this.filters[i]); + } - material.normalMap = this.normalMap; - material.normalScale.copy( this.normalScale ); + this.filters[this.filters.length - 1].connect(this.getOutput()); + } else { + this.source.connect(this.getOutput()); + } - material.specularMap = this.specularMap; + this._connected = true; + return this; + }; - material.envMap = this.envMap; - material.combine = this.combine; - material.reflectivity = this.reflectivity; - material.refractionRatio = this.refractionRatio; + _proto.disconnect = function disconnect() { + if (this.filters.length > 0) { + this.source.disconnect(this.filters[0]); - material.fog = this.fog; + for (var i = 1, l = this.filters.length; i < l; i++) { + this.filters[i - 1].disconnect(this.filters[i]); + } - material.shading = this.shading; + this.filters[this.filters.length - 1].disconnect(this.getOutput()); + } else { + this.source.disconnect(this.getOutput()); + } - material.wireframe = this.wireframe; - material.wireframeLinewidth = this.wireframeLinewidth; - material.wireframeLinecap = this.wireframeLinecap; - material.wireframeLinejoin = this.wireframeLinejoin; + this._connected = false; + return this; + }; - material.vertexColors = this.vertexColors; + _proto.getFilters = function getFilters() { + return this.filters; + }; - material.skinning = this.skinning; - material.morphTargets = this.morphTargets; - material.morphNormals = this.morphNormals; + _proto.setFilters = function setFilters(value) { + if (!value) value = []; - return material; + if (this._connected === true) { + this.disconnect(); + this.filters = value.slice(); + this.connect(); + } else { + this.filters = value.slice(); + } -}; + return this; + }; -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * opacity: , - * - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * wireframe: , - * wireframeLinewidth: - * } - */ + _proto.setDetune = function setDetune(value) { + this.detune = value; + if (this.source.detune === undefined) return; // only set detune when available -THREE.MeshDepthMaterial = function ( parameters ) { + if (this.isPlaying === true) { + this.source.detune.setTargetAtTime(this.detune, this.context.currentTime, 0.01); + } - THREE.Material.call( this ); + return this; + }; - this.morphTargets = false; - this.wireframe = false; - this.wireframeLinewidth = 1; + _proto.getDetune = function getDetune() { + return this.detune; + }; - this.setValues( parameters ); + _proto.getFilter = function getFilter() { + return this.getFilters()[0]; + }; -}; + _proto.setFilter = function setFilter(filter) { + return this.setFilters(filter ? [filter] : []); + }; -THREE.MeshDepthMaterial.prototype = Object.create( THREE.Material.prototype ); + _proto.setPlaybackRate = function setPlaybackRate(value) { + if (this.hasPlaybackControl === false) { + console.warn('THREE.Audio: this Audio has no playback control.'); + return; + } -THREE.MeshDepthMaterial.prototype.clone = function () { + this.playbackRate = value; - var material = new THREE.MeshDepthMaterial(); + if (this.isPlaying === true) { + this.source.playbackRate.setTargetAtTime(this.playbackRate, this.context.currentTime, 0.01); + } - THREE.Material.prototype.clone.call( this, material ); + return this; + }; - material.wireframe = this.wireframe; - material.wireframeLinewidth = this.wireframeLinewidth; + _proto.getPlaybackRate = function getPlaybackRate() { + return this.playbackRate; + }; - return material; + _proto.onEnded = function onEnded() { + this.isPlaying = false; + }; -}; + _proto.getLoop = function getLoop() { + if (this.hasPlaybackControl === false) { + console.warn('THREE.Audio: this Audio has no playback control.'); + return false; + } -/** - * @author mrdoob / http://mrdoob.com/ - * - * parameters = { - * opacity: , - * - * shading: THREE.FlatShading, - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * wireframe: , - * wireframeLinewidth: - * } - */ + return this.loop; + }; -THREE.MeshNormalMaterial = function ( parameters ) { + _proto.setLoop = function setLoop(value) { + if (this.hasPlaybackControl === false) { + console.warn('THREE.Audio: this Audio has no playback control.'); + return; + } - THREE.Material.call( this, parameters ); + this.loop = value; - this.shading = THREE.FlatShading; + if (this.isPlaying === true) { + this.source.loop = this.loop; + } - this.wireframe = false; - this.wireframeLinewidth = 1; + return this; + }; - this.morphTargets = false; + _proto.setLoopStart = function setLoopStart(value) { + this.loopStart = value; + return this; + }; - this.setValues( parameters ); + _proto.setLoopEnd = function setLoopEnd(value) { + this.loopEnd = value; + return this; + }; -}; + _proto.getVolume = function getVolume() { + return this.gain.gain.value; + }; -THREE.MeshNormalMaterial.prototype = Object.create( THREE.Material.prototype ); + _proto.setVolume = function setVolume(value) { + this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01); + return this; + }; -THREE.MeshNormalMaterial.prototype.clone = function () { + return Audio; + }(Object3D); - var material = new THREE.MeshNormalMaterial(); + var _position$3 = /*@__PURE__*/new Vector3(); - THREE.Material.prototype.clone.call( this, material ); + var _quaternion$4 = /*@__PURE__*/new Quaternion(); - material.shading = this.shading; + var _scale$2 = /*@__PURE__*/new Vector3(); - material.wireframe = this.wireframe; - material.wireframeLinewidth = this.wireframeLinewidth; + var _orientation$1 = /*@__PURE__*/new Vector3(); - return material; + var PositionalAudio = /*#__PURE__*/function (_Audio) { + _inheritsLoose(PositionalAudio, _Audio); -}; + function PositionalAudio(listener) { + var _this; -/** - * @author mrdoob / http://mrdoob.com/ - */ + _this = _Audio.call(this, listener) || this; + _this.panner = _this.context.createPanner(); + _this.panner.panningModel = 'HRTF'; -THREE.MeshFaceMaterial = function ( materials ) { + _this.panner.connect(_this.gain); - this.materials = materials instanceof Array ? materials : []; + return _this; + } -}; + var _proto = PositionalAudio.prototype; -THREE.MeshFaceMaterial.prototype.clone = function () { + _proto.getOutput = function getOutput() { + return this.panner; + }; - var material = new THREE.MeshFaceMaterial(); + _proto.getRefDistance = function getRefDistance() { + return this.panner.refDistance; + }; - for ( var i = 0; i < this.materials.length; i ++ ) { + _proto.setRefDistance = function setRefDistance(value) { + this.panner.refDistance = value; + return this; + }; - material.materials.push( this.materials[ i ].clone() ); + _proto.getRolloffFactor = function getRolloffFactor() { + return this.panner.rolloffFactor; + }; - } + _proto.setRolloffFactor = function setRolloffFactor(value) { + this.panner.rolloffFactor = value; + return this; + }; - return material; + _proto.getDistanceModel = function getDistanceModel() { + return this.panner.distanceModel; + }; -}; + _proto.setDistanceModel = function setDistanceModel(value) { + this.panner.distanceModel = value; + return this; + }; -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * map: new THREE.Texture( ), - * - * size: , - * - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * vertexColors: , - * - * fog: - * } - */ + _proto.getMaxDistance = function getMaxDistance() { + return this.panner.maxDistance; + }; -THREE.ParticleSystemMaterial = function ( parameters ) { + _proto.setMaxDistance = function setMaxDistance(value) { + this.panner.maxDistance = value; + return this; + }; - THREE.Material.call( this ); + _proto.setDirectionalCone = function setDirectionalCone(coneInnerAngle, coneOuterAngle, coneOuterGain) { + this.panner.coneInnerAngle = coneInnerAngle; + this.panner.coneOuterAngle = coneOuterAngle; + this.panner.coneOuterGain = coneOuterGain; + return this; + }; - this.color = new THREE.Color( 0xffffff ); + _proto.updateMatrixWorld = function updateMatrixWorld(force) { + _Audio.prototype.updateMatrixWorld.call(this, force); - this.map = null; + if (this.hasPlaybackControl === true && this.isPlaying === false) return; + this.matrixWorld.decompose(_position$3, _quaternion$4, _scale$2); - this.size = 1; - this.sizeAttenuation = true; + _orientation$1.set(0, 0, 1).applyQuaternion(_quaternion$4); - this.vertexColors = false; + var panner = this.panner; - this.fog = true; + if (panner.positionX) { + // code path for Chrome and Firefox (see #14393) + var endTime = this.context.currentTime + this.listener.timeDelta; + panner.positionX.linearRampToValueAtTime(_position$3.x, endTime); + panner.positionY.linearRampToValueAtTime(_position$3.y, endTime); + panner.positionZ.linearRampToValueAtTime(_position$3.z, endTime); + panner.orientationX.linearRampToValueAtTime(_orientation$1.x, endTime); + panner.orientationY.linearRampToValueAtTime(_orientation$1.y, endTime); + panner.orientationZ.linearRampToValueAtTime(_orientation$1.z, endTime); + } else { + panner.setPosition(_position$3.x, _position$3.y, _position$3.z); + panner.setOrientation(_orientation$1.x, _orientation$1.y, _orientation$1.z); + } + }; - this.setValues( parameters ); + return PositionalAudio; + }(Audio); -}; + var AudioAnalyser = /*#__PURE__*/function () { + function AudioAnalyser(audio, fftSize) { + this.analyser = audio.context.createAnalyser(); + this.analyser.fftSize = fftSize !== undefined ? fftSize : 2048; + this.data = new Uint8Array(this.analyser.frequencyBinCount); + audio.getOutput().connect(this.analyser); + } -THREE.ParticleSystemMaterial.prototype = Object.create( THREE.Material.prototype ); + var _proto = AudioAnalyser.prototype; -THREE.ParticleSystemMaterial.prototype.clone = function () { + _proto.getFrequencyData = function getFrequencyData() { + this.analyser.getByteFrequencyData(this.data); + return this.data; + }; - var material = new THREE.ParticleSystemMaterial(); + _proto.getAverageFrequency = function getAverageFrequency() { + var value = 0; + var data = this.getFrequencyData(); - THREE.Material.prototype.clone.call( this, material ); + for (var i = 0; i < data.length; i++) { + value += data[i]; + } - material.color.copy( this.color ); + return value / data.length; + }; - material.map = this.map; + return AudioAnalyser; + }(); - material.size = this.size; - material.sizeAttenuation = this.sizeAttenuation; + function PropertyMixer(binding, typeName, valueSize) { + this.binding = binding; + this.valueSize = valueSize; + var mixFunction, mixFunctionAdditive, setIdentity; // buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ] + // + // interpolators can use .buffer as their .result + // the data then goes to 'incoming' + // + // 'accu0' and 'accu1' are used frame-interleaved for + // the cumulative result and are compared to detect + // changes + // + // 'orig' stores the original state of the property + // + // 'add' is used for additive cumulative results + // + // 'work' is optional and is only present for quaternion types. It is used + // to store intermediate quaternion multiplication results + + switch (typeName) { + case 'quaternion': + mixFunction = this._slerp; + mixFunctionAdditive = this._slerpAdditive; + setIdentity = this._setAdditiveIdentityQuaternion; + this.buffer = new Float64Array(valueSize * 6); + this._workIndex = 5; + break; - material.vertexColors = this.vertexColors; + case 'string': + case 'bool': + mixFunction = this._select; // Use the regular mix function and for additive on these types, + // additive is not relevant for non-numeric types - material.fog = this.fog; + mixFunctionAdditive = this._select; + setIdentity = this._setAdditiveIdentityOther; + this.buffer = new Array(valueSize * 5); + break; - return material; + default: + mixFunction = this._lerp; + mixFunctionAdditive = this._lerpAdditive; + setIdentity = this._setAdditiveIdentityNumeric; + this.buffer = new Float64Array(valueSize * 5); + } + + this._mixBufferRegion = mixFunction; + this._mixBufferRegionAdditive = mixFunctionAdditive; + this._setIdentity = setIdentity; + this._origIndex = 3; + this._addIndex = 4; + this.cumulativeWeight = 0; + this.cumulativeWeightAdditive = 0; + this.useCount = 0; + this.referenceCount = 0; + } + + Object.assign(PropertyMixer.prototype, { + // accumulate data in the 'incoming' region into 'accu' + accumulate: function accumulate(accuIndex, weight) { + // note: happily accumulating nothing when weight = 0, the caller knows + // the weight and shouldn't have made the call in the first place + var buffer = this.buffer, + stride = this.valueSize, + offset = accuIndex * stride + stride; + var currentWeight = this.cumulativeWeight; + + if (currentWeight === 0) { + // accuN := incoming * weight + for (var i = 0; i !== stride; ++i) { + buffer[offset + i] = buffer[i]; + } -}; + currentWeight = weight; + } else { + // accuN := accuN + incoming * weight + currentWeight += weight; + var mix = weight / currentWeight; -// backwards compatibility + this._mixBufferRegion(buffer, offset, 0, mix, stride); + } -THREE.ParticleBasicMaterial = THREE.ParticleSystemMaterial; + this.cumulativeWeight = currentWeight; + }, + // accumulate data in the 'incoming' region into 'add' + accumulateAdditive: function accumulateAdditive(weight) { + var buffer = this.buffer, + stride = this.valueSize, + offset = stride * this._addIndex; -/** - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * fragmentShader: , - * vertexShader: , - * - * uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } }, - * - * defines: { "label" : "value" }, - * - * shading: THREE.SmoothShading, - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * wireframe: , - * wireframeLinewidth: , - * - * lights: , - * - * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, - * - * skinning: , - * morphTargets: , - * morphNormals: , - * - * fog: - * } - */ + if (this.cumulativeWeightAdditive === 0) { + // add = identity + this._setIdentity(); + } // add := add + incoming * weight -THREE.ShaderMaterial = function ( parameters ) { - THREE.Material.call( this ); + this._mixBufferRegionAdditive(buffer, offset, 0, weight, stride); - this.fragmentShader = "void main() {}"; - this.vertexShader = "void main() {}"; - this.uniforms = {}; - this.defines = {}; - this.attributes = null; + this.cumulativeWeightAdditive += weight; + }, + // apply the state of 'accu' to the binding when accus differ + apply: function apply(accuIndex) { + var stride = this.valueSize, + buffer = this.buffer, + offset = accuIndex * stride + stride, + weight = this.cumulativeWeight, + weightAdditive = this.cumulativeWeightAdditive, + binding = this.binding; + this.cumulativeWeight = 0; + this.cumulativeWeightAdditive = 0; - this.shading = THREE.SmoothShading; + if (weight < 1) { + // accuN := accuN + original * ( 1 - cumulativeWeight ) + var originalValueOffset = stride * this._origIndex; - this.linewidth = 1; - - this.wireframe = false; - this.wireframeLinewidth = 1; + this._mixBufferRegion(buffer, offset, originalValueOffset, 1 - weight, stride); + } - this.fog = false; // set to use scene fog + if (weightAdditive > 0) { + // accuN := accuN + additive accuN + this._mixBufferRegionAdditive(buffer, offset, this._addIndex * stride, 1, stride); + } - this.lights = false; // set to use scene lights + for (var i = stride, e = stride + stride; i !== e; ++i) { + if (buffer[i] !== buffer[i + stride]) { + // value has changed -> update scene graph + binding.setValue(buffer, offset); + break; + } + } + }, + // remember the state of the bound property and copy it to both accus + saveOriginalState: function saveOriginalState() { + var binding = this.binding; + var buffer = this.buffer, + stride = this.valueSize, + originalValueOffset = stride * this._origIndex; + binding.getValue(buffer, originalValueOffset); // accu[0..1] := orig -- initially detect changes against the original - this.vertexColors = THREE.NoColors; // set to use "color" attribute stream + for (var i = stride, e = originalValueOffset; i !== e; ++i) { + buffer[i] = buffer[originalValueOffset + i % stride]; + } // Add to identity for additive - this.skinning = false; // set to use skinning attribute streams - this.morphTargets = false; // set to use morph targets - this.morphNormals = false; // set to use morph normals + this._setIdentity(); - // When rendered geometry doesn't include these attributes but the material does, - // use these default values in WebGL. This avoids errors when buffer data is missing. - this.defaultAttributeValues = { - "color" : [ 1, 1, 1 ], - "uv" : [ 0, 0 ], - "uv2" : [ 0, 0 ] - }; + this.cumulativeWeight = 0; + this.cumulativeWeightAdditive = 0; + }, + // apply the state previously taken via 'saveOriginalState' to the binding + restoreOriginalState: function restoreOriginalState() { + var originalValueOffset = this.valueSize * 3; + this.binding.setValue(this.buffer, originalValueOffset); + }, + _setAdditiveIdentityNumeric: function _setAdditiveIdentityNumeric() { + var startIndex = this._addIndex * this.valueSize; + var endIndex = startIndex + this.valueSize; - this.index0AttributeName = undefined; + for (var i = startIndex; i < endIndex; i++) { + this.buffer[i] = 0; + } + }, + _setAdditiveIdentityQuaternion: function _setAdditiveIdentityQuaternion() { + this._setAdditiveIdentityNumeric(); - this.setValues( parameters ); + this.buffer[this._addIndex * this.valueSize + 3] = 1; + }, + _setAdditiveIdentityOther: function _setAdditiveIdentityOther() { + var startIndex = this._origIndex * this.valueSize; + var targetIndex = this._addIndex * this.valueSize; -}; + for (var i = 0; i < this.valueSize; i++) { + this.buffer[targetIndex + i] = this.buffer[startIndex + i]; + } + }, + // mix functions + _select: function _select(buffer, dstOffset, srcOffset, t, stride) { + if (t >= 0.5) { + for (var i = 0; i !== stride; ++i) { + buffer[dstOffset + i] = buffer[srcOffset + i]; + } + } + }, + _slerp: function _slerp(buffer, dstOffset, srcOffset, t) { + Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t); + }, + _slerpAdditive: function _slerpAdditive(buffer, dstOffset, srcOffset, t, stride) { + var workOffset = this._workIndex * stride; // Store result in intermediate buffer offset -THREE.ShaderMaterial.prototype = Object.create( THREE.Material.prototype ); + Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset); // Slerp to the intermediate result -THREE.ShaderMaterial.prototype.clone = function () { + Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t); + }, + _lerp: function _lerp(buffer, dstOffset, srcOffset, t, stride) { + var s = 1 - t; - var material = new THREE.ShaderMaterial(); + for (var i = 0; i !== stride; ++i) { + var j = dstOffset + i; + buffer[j] = buffer[j] * s + buffer[srcOffset + i] * t; + } + }, + _lerpAdditive: function _lerpAdditive(buffer, dstOffset, srcOffset, t, stride) { + for (var i = 0; i !== stride; ++i) { + var j = dstOffset + i; + buffer[j] = buffer[j] + buffer[srcOffset + i] * t; + } + } + }); - THREE.Material.prototype.clone.call( this, material ); + // Characters [].:/ are reserved for track binding syntax. + var _RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; - material.fragmentShader = this.fragmentShader; - material.vertexShader = this.vertexShader; + var _reservedRe = new RegExp('[' + _RESERVED_CHARS_RE + ']', 'g'); // Attempts to allow node names from any language. ES5's `\w` regexp matches + // only latin characters, and the unicode \p{L} is not yet supported. So + // instead, we exclude reserved characters and match everything else. - material.uniforms = THREE.UniformsUtils.clone( this.uniforms ); - material.attributes = this.attributes; - material.defines = this.defines; + var _wordChar = '[^' + _RESERVED_CHARS_RE + ']'; - material.shading = this.shading; + var _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace('\\.', '') + ']'; // Parent directories, delimited by '/' or ':'. Currently unused, but must + // be matched to parse the rest of the track name. - material.wireframe = this.wireframe; - material.wireframeLinewidth = this.wireframeLinewidth; - material.fog = this.fog; + var _directoryRe = /((?:WC+[\/:])*)/.source.replace('WC', _wordChar); // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. - material.lights = this.lights; - material.vertexColors = this.vertexColors; + var _nodeRe = /(WCOD+)?/.source.replace('WCOD', _wordCharOrDot); // Object on target node, and accessor. May not contain reserved + // characters. Accessor may contain any character except closing bracket. - material.skinning = this.skinning; - material.morphTargets = this.morphTargets; - material.morphNormals = this.morphNormals; + var _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace('WC', _wordChar); // Property and accessor. May not contain reserved characters. Accessor may + // contain any non-bracket characters. - return material; -}; + var _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace('WC', _wordChar); -/** - * @author mrdoob / http://mrdoob.com/ - */ + var _trackRe = new RegExp('' + '^' + _directoryRe + _nodeRe + _objectRe + _propertyRe + '$'); -THREE.RawShaderMaterial = function ( parameters ) { + var _supportedObjectNames = ['material', 'materials', 'bones']; - THREE.ShaderMaterial.call( this, parameters ); + function Composite(targetGroup, path, optionalParsedPath) { + var parsedPath = optionalParsedPath || PropertyBinding.parseTrackName(path); + this._targetGroup = targetGroup; + this._bindings = targetGroup.subscribe_(path, parsedPath); + } -}; + Object.assign(Composite.prototype, { + getValue: function getValue(array, offset) { + this.bind(); // bind all binding -THREE.RawShaderMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype ); + var firstValidIndex = this._targetGroup.nCachedObjects_, + binding = this._bindings[firstValidIndex]; // and only call .getValue on the first -THREE.RawShaderMaterial.prototype.clone = function () { + if (binding !== undefined) binding.getValue(array, offset); + }, + setValue: function setValue(array, offset) { + var bindings = this._bindings; - var material = new THREE.RawShaderMaterial(); + for (var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { + bindings[i].setValue(array, offset); + } + }, + bind: function bind() { + var bindings = this._bindings; - THREE.ShaderMaterial.prototype.clone.call( this, material ); + for (var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { + bindings[i].bind(); + } + }, + unbind: function unbind() { + var bindings = this._bindings; - return material; + for (var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { + bindings[i].unbind(); + } + } + }); -}; + function PropertyBinding(rootNode, path, parsedPath) { + this.path = path; + this.parsedPath = parsedPath || PropertyBinding.parseTrackName(path); + this.node = PropertyBinding.findNode(rootNode, this.parsedPath.nodeName) || rootNode; + this.rootNode = rootNode; + } -/** - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * map: new THREE.Texture( ), - * - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * uvOffset: new THREE.Vector2(), - * uvScale: new THREE.Vector2(), - * - * fog: - * } - */ + Object.assign(PropertyBinding, { + Composite: Composite, + create: function create(root, path, parsedPath) { + if (!(root && root.isAnimationObjectGroup)) { + return new PropertyBinding(root, path, parsedPath); + } else { + return new PropertyBinding.Composite(root, path, parsedPath); + } + }, -THREE.SpriteMaterial = function ( parameters ) { + /** + * Replaces spaces with underscores and removes unsupported characters from + * node names, to ensure compatibility with parseTrackName(). + * + * @param {string} name Node name to be sanitized. + * @return {string} + */ + sanitizeNodeName: function sanitizeNodeName(name) { + return name.replace(/\s/g, '_').replace(_reservedRe, ''); + }, + parseTrackName: function parseTrackName(trackName) { + var matches = _trackRe.exec(trackName); - THREE.Material.call( this ); + if (!matches) { + throw new Error('PropertyBinding: Cannot parse trackName: ' + trackName); + } - // defaults + var results = { + // directoryName: matches[ 1 ], // (tschw) currently unused + nodeName: matches[2], + objectName: matches[3], + objectIndex: matches[4], + propertyName: matches[5], + // required + propertyIndex: matches[6] + }; + var lastDot = results.nodeName && results.nodeName.lastIndexOf('.'); - this.color = new THREE.Color( 0xffffff ); - this.map = null; + if (lastDot !== undefined && lastDot !== -1) { + var objectName = results.nodeName.substring(lastDot + 1); // Object names must be checked against an allowlist. Otherwise, there + // is no way to parse 'foo.bar.baz': 'baz' must be a property, but + // 'bar' could be the objectName, or part of a nodeName (which can + // include '.' characters). - this.rotation = 0; + if (_supportedObjectNames.indexOf(objectName) !== -1) { + results.nodeName = results.nodeName.substring(0, lastDot); + results.objectName = objectName; + } + } - this.fog = false; + if (results.propertyName === null || results.propertyName.length === 0) { + throw new Error('PropertyBinding: can not parse propertyName from trackName: ' + trackName); + } - // set parameters + return results; + }, + findNode: function findNode(root, nodeName) { + if (!nodeName || nodeName === "" || nodeName === "." || nodeName === -1 || nodeName === root.name || nodeName === root.uuid) { + return root; + } // search into skeleton bones. - this.setValues( parameters ); -}; + if (root.skeleton) { + var bone = root.skeleton.getBoneByName(nodeName); -THREE.SpriteMaterial.prototype = Object.create( THREE.Material.prototype ); + if (bone !== undefined) { + return bone; + } + } // search into node subtree. -THREE.SpriteMaterial.prototype.clone = function () { - var material = new THREE.SpriteMaterial(); + if (root.children) { + var searchNodeSubtree = function searchNodeSubtree(children) { + for (var i = 0; i < children.length; i++) { + var childNode = children[i]; - THREE.Material.prototype.clone.call( this, material ); + if (childNode.name === nodeName || childNode.uuid === nodeName) { + return childNode; + } - material.color.copy( this.color ); - material.map = this.map; + var result = searchNodeSubtree(childNode.children); + if (result) return result; + } - material.rotation = this.rotation; + return null; + }; - material.fog = this.fog; + var subTreeNode = searchNodeSubtree(root.children); - return material; + if (subTreeNode) { + return subTreeNode; + } + } -}; + return null; + } + }); + Object.assign(PropertyBinding.prototype, { + // prototype, continued + // these are used to "bind" a nonexistent property + _getValue_unavailable: function _getValue_unavailable() {}, + _setValue_unavailable: function _setValue_unavailable() {}, + BindingType: { + Direct: 0, + EntireArray: 1, + ArrayElement: 2, + HasFromToArray: 3 + }, + Versioning: { + None: 0, + NeedsUpdate: 1, + MatrixWorldNeedsUpdate: 2 + }, + GetterByBindingType: [function getValue_direct(buffer, offset) { + buffer[offset] = this.node[this.propertyName]; + }, function getValue_array(buffer, offset) { + var source = this.resolvedProperty; + + for (var i = 0, n = source.length; i !== n; ++i) { + buffer[offset++] = source[i]; + } + }, function getValue_arrayElement(buffer, offset) { + buffer[offset] = this.resolvedProperty[this.propertyIndex]; + }, function getValue_toArray(buffer, offset) { + this.resolvedProperty.toArray(buffer, offset); + }], + SetterByBindingTypeAndVersioning: [[// Direct + function setValue_direct(buffer, offset) { + this.targetObject[this.propertyName] = buffer[offset]; + }, function setValue_direct_setNeedsUpdate(buffer, offset) { + this.targetObject[this.propertyName] = buffer[offset]; + this.targetObject.needsUpdate = true; + }, function setValue_direct_setMatrixWorldNeedsUpdate(buffer, offset) { + this.targetObject[this.propertyName] = buffer[offset]; + this.targetObject.matrixWorldNeedsUpdate = true; + }], [// EntireArray + function setValue_array(buffer, offset) { + var dest = this.resolvedProperty; + + for (var i = 0, n = dest.length; i !== n; ++i) { + dest[i] = buffer[offset++]; + } + }, function setValue_array_setNeedsUpdate(buffer, offset) { + var dest = this.resolvedProperty; + + for (var i = 0, n = dest.length; i !== n; ++i) { + dest[i] = buffer[offset++]; + } + + this.targetObject.needsUpdate = true; + }, function setValue_array_setMatrixWorldNeedsUpdate(buffer, offset) { + var dest = this.resolvedProperty; + + for (var i = 0, n = dest.length; i !== n; ++i) { + dest[i] = buffer[offset++]; + } + + this.targetObject.matrixWorldNeedsUpdate = true; + }], [// ArrayElement + function setValue_arrayElement(buffer, offset) { + this.resolvedProperty[this.propertyIndex] = buffer[offset]; + }, function setValue_arrayElement_setNeedsUpdate(buffer, offset) { + this.resolvedProperty[this.propertyIndex] = buffer[offset]; + this.targetObject.needsUpdate = true; + }, function setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer, offset) { + this.resolvedProperty[this.propertyIndex] = buffer[offset]; + this.targetObject.matrixWorldNeedsUpdate = true; + }], [// HasToFromArray + function setValue_fromArray(buffer, offset) { + this.resolvedProperty.fromArray(buffer, offset); + }, function setValue_fromArray_setNeedsUpdate(buffer, offset) { + this.resolvedProperty.fromArray(buffer, offset); + this.targetObject.needsUpdate = true; + }, function setValue_fromArray_setMatrixWorldNeedsUpdate(buffer, offset) { + this.resolvedProperty.fromArray(buffer, offset); + this.targetObject.matrixWorldNeedsUpdate = true; + }]], + getValue: function getValue_unbound(targetArray, offset) { + this.bind(); + this.getValue(targetArray, offset); // Note: This class uses a State pattern on a per-method basis: + // 'bind' sets 'this.getValue' / 'setValue' and shadows the + // prototype version of these methods with one that represents + // the bound state. When the property is not found, the methods + // become no-ops. + }, + setValue: function getValue_unbound(sourceArray, offset) { + this.bind(); + this.setValue(sourceArray, offset); + }, + // create getter / setter pair for a property in the scene graph + bind: function bind() { + var targetObject = this.node; + var parsedPath = this.parsedPath; + var objectName = parsedPath.objectName; + var propertyName = parsedPath.propertyName; + var propertyIndex = parsedPath.propertyIndex; -/** - * @author mrdoob / http://mrdoob.com/ - * - * parameters = { - * color: , - * program: , - * opacity: , - * blending: THREE.NormalBlending - * } - */ + if (!targetObject) { + targetObject = PropertyBinding.findNode(this.rootNode, parsedPath.nodeName) || this.rootNode; + this.node = targetObject; + } // set fail state so we can just 'return' on error -THREE.SpriteCanvasMaterial = function ( parameters ) { - THREE.Material.call( this ); + this.getValue = this._getValue_unavailable; + this.setValue = this._setValue_unavailable; // ensure there is a value node - this.color = new THREE.Color( 0xffffff ); - this.program = function ( context, color ) {}; + if (!targetObject) { + console.error('THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.'); + return; + } - this.setValues( parameters ); + if (objectName) { + var objectIndex = parsedPath.objectIndex; // special cases were we need to reach deeper into the hierarchy to get the face materials.... -}; + switch (objectName) { + case 'materials': + if (!targetObject.material) { + console.error('THREE.PropertyBinding: Can not bind to material as node does not have a material.', this); + return; + } -THREE.SpriteCanvasMaterial.prototype = Object.create( THREE.Material.prototype ); + if (!targetObject.material.materials) { + console.error('THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this); + return; + } -THREE.SpriteCanvasMaterial.prototype.clone = function () { + targetObject = targetObject.material.materials; + break; - var material = new THREE.SpriteCanvasMaterial(); + case 'bones': + if (!targetObject.skeleton) { + console.error('THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this); + return; + } // potential future optimization: skip this if propertyIndex is already an integer + // and convert the integer string to a true integer. - THREE.Material.prototype.clone.call( this, material ); - material.color.copy( this.color ); - material.program = this.program; + targetObject = targetObject.skeleton.bones; // support resolving morphTarget names into indices. - return material; + for (var i = 0; i < targetObject.length; i++) { + if (targetObject[i].name === objectIndex) { + objectIndex = i; + break; + } + } -}; + break; -// backwards compatibility + default: + if (targetObject[objectName] === undefined) { + console.error('THREE.PropertyBinding: Can not bind to objectName of node undefined.', this); + return; + } -THREE.ParticleCanvasMaterial = THREE.SpriteCanvasMaterial; -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author szimek / https://github.com/szimek/ - */ + targetObject = targetObject[objectName]; + } -THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { + if (objectIndex !== undefined) { + if (targetObject[objectIndex] === undefined) { + console.error('THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject); + return; + } - this.id = THREE.TextureIdCount ++; - this.uuid = THREE.Math.generateUUID(); + targetObject = targetObject[objectIndex]; + } + } // resolve property - this.name = ''; - this.image = image; - this.mipmaps = []; + var nodeProperty = targetObject[propertyName]; - this.mapping = mapping !== undefined ? mapping : new THREE.UVMapping(); + if (nodeProperty === undefined) { + var nodeName = parsedPath.nodeName; + console.error('THREE.PropertyBinding: Trying to update property for track: ' + nodeName + '.' + propertyName + ' but it wasn\'t found.', targetObject); + return; + } // determine versioning scheme - this.wrapS = wrapS !== undefined ? wrapS : THREE.ClampToEdgeWrapping; - this.wrapT = wrapT !== undefined ? wrapT : THREE.ClampToEdgeWrapping; - this.magFilter = magFilter !== undefined ? magFilter : THREE.LinearFilter; - this.minFilter = minFilter !== undefined ? minFilter : THREE.LinearMipMapLinearFilter; + var versioning = this.Versioning.None; + this.targetObject = targetObject; - this.anisotropy = anisotropy !== undefined ? anisotropy : 1; + if (targetObject.needsUpdate !== undefined) { + // material + versioning = this.Versioning.NeedsUpdate; + } else if (targetObject.matrixWorldNeedsUpdate !== undefined) { + // node transform + versioning = this.Versioning.MatrixWorldNeedsUpdate; + } // determine how the property gets bound - this.format = format !== undefined ? format : THREE.RGBAFormat; - this.type = type !== undefined ? type : THREE.UnsignedByteType; - this.offset = new THREE.Vector2( 0, 0 ); - this.repeat = new THREE.Vector2( 1, 1 ); + var bindingType = this.BindingType.Direct; - this.generateMipmaps = true; - this.premultiplyAlpha = false; - this.flipY = true; - this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) + if (propertyIndex !== undefined) { + // access a sub element of the property array (only primitives are supported right now) + if (propertyName === "morphTargetInfluences") { + // potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer. + // support resolving morphTarget names into indices. + if (!targetObject.geometry) { + console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this); + return; + } - this._needsUpdate = false; - this.onUpdate = null; + if (targetObject.geometry.isBufferGeometry) { + if (!targetObject.geometry.morphAttributes) { + console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this); + return; + } -}; + if (targetObject.morphTargetDictionary[propertyIndex] !== undefined) { + propertyIndex = targetObject.morphTargetDictionary[propertyIndex]; + } + } else { + console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences on THREE.Geometry. Use THREE.BufferGeometry instead.', this); + return; + } + } -THREE.Texture.prototype = { + bindingType = this.BindingType.ArrayElement; + this.resolvedProperty = nodeProperty; + this.propertyIndex = propertyIndex; + } else if (nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined) { + // must use copy for Object3D.Euler/Quaternion + bindingType = this.BindingType.HasFromToArray; + this.resolvedProperty = nodeProperty; + } else if (Array.isArray(nodeProperty)) { + bindingType = this.BindingType.EntireArray; + this.resolvedProperty = nodeProperty; + } else { + this.propertyName = propertyName; + } // select getter / setter - constructor: THREE.Texture, - get needsUpdate () { + this.getValue = this.GetterByBindingType[bindingType]; + this.setValue = this.SetterByBindingTypeAndVersioning[bindingType][versioning]; + }, + unbind: function unbind() { + this.node = null; // back to the prototype version of getValue / setValue + // note: avoiding to mutate the shape of 'this' via 'delete' - return this._needsUpdate; + this.getValue = this._getValue_unbound; + this.setValue = this._setValue_unbound; + } + }); // DECLARE ALIAS AFTER assign prototype - }, + Object.assign(PropertyBinding.prototype, { + // initial state of these methods that calls 'bind' + _getValue_unbound: PropertyBinding.prototype.getValue, + _setValue_unbound: PropertyBinding.prototype.setValue + }); - set needsUpdate ( value ) { + /** + * + * A group of objects that receives a shared animation state. + * + * Usage: + * + * - Add objects you would otherwise pass as 'root' to the + * constructor or the .clipAction method of AnimationMixer. + * + * - Instead pass this object as 'root'. + * + * - You can also add and remove objects later when the mixer + * is running. + * + * Note: + * + * Objects of this class appear as one object to the mixer, + * so cache control of the individual objects must be done + * on the group. + * + * Limitation: + * + * - The animated properties must be compatible among the + * all objects in the group. + * + * - A single property can either be controlled through a + * target group or directly, but not both. + */ - if ( value === true ) this.update(); + function AnimationObjectGroup() { + this.uuid = MathUtils.generateUUID(); // cached objects followed by the active ones - this._needsUpdate = value; + this._objects = Array.prototype.slice.call(arguments); + this.nCachedObjects_ = 0; // threshold + // note: read by PropertyBinding.Composite - }, + var indices = {}; + this._indicesByUUID = indices; // for bookkeeping - clone: function ( texture ) { + for (var i = 0, n = arguments.length; i !== n; ++i) { + indices[arguments[i].uuid] = i; + } - if ( texture === undefined ) texture = new THREE.Texture(); + this._paths = []; // inside: string - texture.image = this.image; - texture.mipmaps = this.mipmaps.slice(0); + this._parsedPaths = []; // inside: { we don't care, here } - texture.mapping = this.mapping; + this._bindings = []; // inside: Array< PropertyBinding > - texture.wrapS = this.wrapS; - texture.wrapT = this.wrapT; + this._bindingsIndicesByPath = {}; // inside: indices in these arrays - texture.magFilter = this.magFilter; - texture.minFilter = this.minFilter; + var scope = this; + this.stats = { + objects: { + get total() { + return scope._objects.length; + }, + + get inUse() { + return this.total - scope.nCachedObjects_; + } - texture.anisotropy = this.anisotropy; + }, - texture.format = this.format; - texture.type = this.type; + get bindingsPerObject() { + return scope._bindings.length; + } - texture.offset.copy( this.offset ); - texture.repeat.copy( this.repeat ); + }; + } - texture.generateMipmaps = this.generateMipmaps; - texture.premultiplyAlpha = this.premultiplyAlpha; - texture.flipY = this.flipY; - texture.unpackAlignment = this.unpackAlignment; + Object.assign(AnimationObjectGroup.prototype, { + isAnimationObjectGroup: true, + add: function add() { + var objects = this._objects, + indicesByUUID = this._indicesByUUID, + paths = this._paths, + parsedPaths = this._parsedPaths, + bindings = this._bindings, + nBindings = bindings.length; + var knownObject = undefined, + nObjects = objects.length, + nCachedObjects = this.nCachedObjects_; + + for (var i = 0, n = arguments.length; i !== n; ++i) { + var object = arguments[i], + uuid = object.uuid; + var index = indicesByUUID[uuid]; + + if (index === undefined) { + // unknown object -> add it to the ACTIVE region + index = nObjects++; + indicesByUUID[uuid] = index; + objects.push(object); // accounting is done, now do the same for all bindings + + for (var j = 0, m = nBindings; j !== m; ++j) { + bindings[j].push(new PropertyBinding(object, paths[j], parsedPaths[j])); + } + } else if (index < nCachedObjects) { + knownObject = objects[index]; // move existing object to the ACTIVE region + + var firstActiveIndex = --nCachedObjects, + lastCachedObject = objects[firstActiveIndex]; + indicesByUUID[lastCachedObject.uuid] = index; + objects[index] = lastCachedObject; + indicesByUUID[uuid] = firstActiveIndex; + objects[firstActiveIndex] = object; // accounting is done, now do the same for all bindings + + for (var _j = 0, _m = nBindings; _j !== _m; ++_j) { + var bindingsForPath = bindings[_j], + lastCached = bindingsForPath[firstActiveIndex]; + var binding = bindingsForPath[index]; + bindingsForPath[index] = lastCached; + + if (binding === undefined) { + // since we do not bother to create new bindings + // for objects that are cached, the binding may + // or may not exist + binding = new PropertyBinding(object, paths[_j], parsedPaths[_j]); + } - return texture; + bindingsForPath[firstActiveIndex] = binding; + } + } else if (objects[index] !== knownObject) { + console.error('THREE.AnimationObjectGroup: Different objects with the same UUID ' + 'detected. Clean the caches or recreate your infrastructure when reloading scenes.'); + } // else the object is already where we want it to be - }, + } // for arguments - update: function () { - this.dispatchEvent( { type: 'update' } ); + this.nCachedObjects_ = nCachedObjects; + }, + remove: function remove() { + var objects = this._objects, + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; + var nCachedObjects = this.nCachedObjects_; + + for (var i = 0, n = arguments.length; i !== n; ++i) { + var object = arguments[i], + uuid = object.uuid, + index = indicesByUUID[uuid]; + + if (index !== undefined && index >= nCachedObjects) { + // move existing object into the CACHED region + var lastCachedIndex = nCachedObjects++, + firstActiveObject = objects[lastCachedIndex]; + indicesByUUID[firstActiveObject.uuid] = index; + objects[index] = firstActiveObject; + indicesByUUID[uuid] = lastCachedIndex; + objects[lastCachedIndex] = object; // accounting is done, now do the same for all bindings + + for (var j = 0, m = nBindings; j !== m; ++j) { + var bindingsForPath = bindings[j], + firstActive = bindingsForPath[lastCachedIndex], + binding = bindingsForPath[index]; + bindingsForPath[index] = firstActive; + bindingsForPath[lastCachedIndex] = binding; + } + } + } // for arguments - }, - dispose: function () { + this.nCachedObjects_ = nCachedObjects; + }, + // remove & forget + uncache: function uncache() { + var objects = this._objects, + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; + var nCachedObjects = this.nCachedObjects_, + nObjects = objects.length; + + for (var i = 0, n = arguments.length; i !== n; ++i) { + var object = arguments[i], + uuid = object.uuid, + index = indicesByUUID[uuid]; + + if (index !== undefined) { + delete indicesByUUID[uuid]; + + if (index < nCachedObjects) { + // object is cached, shrink the CACHED region + var firstActiveIndex = --nCachedObjects, + lastCachedObject = objects[firstActiveIndex], + lastIndex = --nObjects, + lastObject = objects[lastIndex]; // last cached object takes this object's place + + indicesByUUID[lastCachedObject.uuid] = index; + objects[index] = lastCachedObject; // last object goes to the activated slot and pop + + indicesByUUID[lastObject.uuid] = firstActiveIndex; + objects[firstActiveIndex] = lastObject; + objects.pop(); // accounting is done, now do the same for all bindings + + for (var j = 0, m = nBindings; j !== m; ++j) { + var bindingsForPath = bindings[j], + lastCached = bindingsForPath[firstActiveIndex], + last = bindingsForPath[lastIndex]; + bindingsForPath[index] = lastCached; + bindingsForPath[firstActiveIndex] = last; + bindingsForPath.pop(); + } + } else { + // object is active, just swap with the last and pop + var _lastIndex = --nObjects, + _lastObject = objects[_lastIndex]; - this.dispatchEvent( { type: 'dispose' } ); + if (_lastIndex > 0) { + indicesByUUID[_lastObject.uuid] = index; + } - } + objects[index] = _lastObject; + objects.pop(); // accounting is done, now do the same for all bindings -}; + for (var _j2 = 0, _m2 = nBindings; _j2 !== _m2; ++_j2) { + var _bindingsForPath = bindings[_j2]; + _bindingsForPath[index] = _bindingsForPath[_lastIndex]; -THREE.EventDispatcher.prototype.apply( THREE.Texture.prototype ); + _bindingsForPath.pop(); + } + } // cached or active -THREE.TextureIdCount = 0; + } // if object is known -/** - * @author alteredq / http://alteredqualia.com/ - */ + } // for arguments -THREE.CompressedTexture = function ( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy ) { - THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + this.nCachedObjects_ = nCachedObjects; + }, + // Internal interface used by befriended PropertyBinding.Composite: + subscribe_: function subscribe_(path, parsedPath) { + // returns an array of bindings for the given path that is changed + // according to the contained objects in the group + var indicesByPath = this._bindingsIndicesByPath; + var index = indicesByPath[path]; + var bindings = this._bindings; + if (index !== undefined) return bindings[index]; + var paths = this._paths, + parsedPaths = this._parsedPaths, + objects = this._objects, + nObjects = objects.length, + nCachedObjects = this.nCachedObjects_, + bindingsForPath = new Array(nObjects); + index = bindings.length; + indicesByPath[path] = index; + paths.push(path); + parsedPaths.push(parsedPath); + bindings.push(bindingsForPath); + + for (var i = nCachedObjects, n = objects.length; i !== n; ++i) { + var object = objects[i]; + bindingsForPath[i] = new PropertyBinding(object, path, parsedPath); + } + + return bindingsForPath; + }, + unsubscribe_: function unsubscribe_(path) { + // tells the group to forget about a property path and no longer + // update the array previously obtained with 'subscribe_' + var indicesByPath = this._bindingsIndicesByPath, + index = indicesByPath[path]; + + if (index !== undefined) { + var paths = this._paths, + parsedPaths = this._parsedPaths, + bindings = this._bindings, + lastBindingsIndex = bindings.length - 1, + lastBindings = bindings[lastBindingsIndex], + lastBindingsPath = path[lastBindingsIndex]; + indicesByPath[lastBindingsPath] = index; + bindings[index] = lastBindings; + bindings.pop(); + parsedPaths[index] = parsedPaths[lastBindingsIndex]; + parsedPaths.pop(); + paths[index] = paths[lastBindingsIndex]; + paths.pop(); + } + } + }); + + var AnimationAction = /*#__PURE__*/function () { + function AnimationAction(mixer, clip, localRoot, blendMode) { + this._mixer = mixer; + this._clip = clip; + this._localRoot = localRoot || null; + this.blendMode = blendMode || clip.blendMode; + var tracks = clip.tracks, + nTracks = tracks.length, + interpolants = new Array(nTracks); + var interpolantSettings = { + endingStart: ZeroCurvatureEnding, + endingEnd: ZeroCurvatureEnding + }; - this.image = { width: width, height: height }; - this.mipmaps = mipmaps; + for (var i = 0; i !== nTracks; ++i) { + var interpolant = tracks[i].createInterpolant(null); + interpolants[i] = interpolant; + interpolant.settings = interpolantSettings; + } - this.generateMipmaps = false; // WebGL currently can't generate mipmaps for compressed textures, they must be embedded in DDS file + this._interpolantSettings = interpolantSettings; + this._interpolants = interpolants; // bound by the mixer + // inside: PropertyMixer (managed by the mixer) -}; + this._propertyBindings = new Array(nTracks); + this._cacheIndex = null; // for the memory manager -THREE.CompressedTexture.prototype = Object.create( THREE.Texture.prototype ); + this._byClipCacheIndex = null; // for the memory manager -THREE.CompressedTexture.prototype.clone = function () { + this._timeScaleInterpolant = null; + this._weightInterpolant = null; + this.loop = LoopRepeat; + this._loopCount = -1; // global mixer time when the action is to be started + // it's set back to 'null' upon start of the action - var texture = new THREE.CompressedTexture(); + this._startTime = null; // scaled local time of the action + // gets clamped or wrapped to 0..clip.duration according to loop - THREE.Texture.prototype.clone.call( this, texture ); + this.time = 0; + this.timeScale = 1; + this._effectiveTimeScale = 1; + this.weight = 1; + this._effectiveWeight = 1; + this.repetitions = Infinity; // no. of repetitions when looping - return texture; + this.paused = false; // true -> zero effective time scale -}; + this.enabled = true; // false -> zero effective weight -/** - * @author alteredq / http://alteredqualia.com/ - */ + this.clampWhenFinished = false; // keep feeding the last frame? -THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy ) { + this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate - THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + this.zeroSlopeAtEnd = true; // clips for start, loop and end + } // State & Scheduling - this.image = { data: data, width: width, height: height }; -}; + var _proto = AnimationAction.prototype; -THREE.DataTexture.prototype = Object.create( THREE.Texture.prototype ); + _proto.play = function play() { + this._mixer._activateAction(this); -THREE.DataTexture.prototype.clone = function () { + return this; + }; - var texture = new THREE.DataTexture(); + _proto.stop = function stop() { + this._mixer._deactivateAction(this); - THREE.Texture.prototype.clone.call( this, texture ); + return this.reset(); + }; - return texture; + _proto.reset = function reset() { + this.paused = false; + this.enabled = true; + this.time = 0; // restart clip -}; + this._loopCount = -1; // forget previous loops -/** - * @author alteredq / http://alteredqualia.com/ - */ + this._startTime = null; // forget scheduling -THREE.ParticleSystem = function ( geometry, material ) { + return this.stopFading().stopWarping(); + }; - THREE.Object3D.call( this ); + _proto.isRunning = function isRunning() { + return this.enabled && !this.paused && this.timeScale !== 0 && this._startTime === null && this._mixer._isActiveAction(this); + } // return true when play has been called + ; - this.geometry = geometry !== undefined ? geometry : new THREE.Geometry(); - this.material = material !== undefined ? material : new THREE.ParticleSystemMaterial( { color: Math.random() * 0xffffff } ); + _proto.isScheduled = function isScheduled() { + return this._mixer._isActiveAction(this); + }; - this.sortParticles = false; - this.frustumCulled = false; + _proto.startAt = function startAt(time) { + this._startTime = time; + return this; + }; -}; + _proto.setLoop = function setLoop(mode, repetitions) { + this.loop = mode; + this.repetitions = repetitions; + return this; + } // Weight + // set the weight stopping any scheduled fading + // although .enabled = false yields an effective weight of zero, this + // method does *not* change .enabled, because it would be confusing + ; + + _proto.setEffectiveWeight = function setEffectiveWeight(weight) { + this.weight = weight; // note: same logic as when updated at runtime + + this._effectiveWeight = this.enabled ? weight : 0; + return this.stopFading(); + } // return the weight considering fading and .enabled + ; + + _proto.getEffectiveWeight = function getEffectiveWeight() { + return this._effectiveWeight; + }; -THREE.ParticleSystem.prototype = Object.create( THREE.Object3D.prototype ); + _proto.fadeIn = function fadeIn(duration) { + return this._scheduleFading(duration, 0, 1); + }; -THREE.ParticleSystem.prototype.clone = function ( object ) { + _proto.fadeOut = function fadeOut(duration) { + return this._scheduleFading(duration, 1, 0); + }; - if ( object === undefined ) object = new THREE.ParticleSystem( this.geometry, this.material ); + _proto.crossFadeFrom = function crossFadeFrom(fadeOutAction, duration, warp) { + fadeOutAction.fadeOut(duration); + this.fadeIn(duration); - object.sortParticles = this.sortParticles; + if (warp) { + var fadeInDuration = this._clip.duration, + fadeOutDuration = fadeOutAction._clip.duration, + startEndRatio = fadeOutDuration / fadeInDuration, + endStartRatio = fadeInDuration / fadeOutDuration; + fadeOutAction.warp(1.0, startEndRatio, duration); + this.warp(endStartRatio, 1.0, duration); + } - THREE.Object3D.prototype.clone.call( this, object ); + return this; + }; - return object; + _proto.crossFadeTo = function crossFadeTo(fadeInAction, duration, warp) { + return fadeInAction.crossFadeFrom(this, duration, warp); + }; -}; + _proto.stopFading = function stopFading() { + var weightInterpolant = this._weightInterpolant; -/** - * @author mrdoob / http://mrdoob.com/ - */ + if (weightInterpolant !== null) { + this._weightInterpolant = null; -THREE.Line = function ( geometry, material, type ) { + this._mixer._takeBackControlInterpolant(weightInterpolant); + } - THREE.Object3D.call( this ); + return this; + } // Time Scale Control + // set the time scale stopping any scheduled warping + // although .paused = true yields an effective time scale of zero, this + // method does *not* change .paused, because it would be confusing + ; + + _proto.setEffectiveTimeScale = function setEffectiveTimeScale(timeScale) { + this.timeScale = timeScale; + this._effectiveTimeScale = this.paused ? 0 : timeScale; + return this.stopWarping(); + } // return the time scale considering warping and .paused + ; + + _proto.getEffectiveTimeScale = function getEffectiveTimeScale() { + return this._effectiveTimeScale; + }; - this.geometry = geometry !== undefined ? geometry : new THREE.Geometry(); - this.material = material !== undefined ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } ); + _proto.setDuration = function setDuration(duration) { + this.timeScale = this._clip.duration / duration; + return this.stopWarping(); + }; - this.type = ( type !== undefined ) ? type : THREE.LineStrip; + _proto.syncWith = function syncWith(action) { + this.time = action.time; + this.timeScale = action.timeScale; + return this.stopWarping(); + }; -}; + _proto.halt = function halt(duration) { + return this.warp(this._effectiveTimeScale, 0, duration); + }; -THREE.LineStrip = 0; -THREE.LinePieces = 1; + _proto.warp = function warp(startTimeScale, endTimeScale, duration) { + var mixer = this._mixer, + now = mixer.time, + timeScale = this.timeScale; + var interpolant = this._timeScaleInterpolant; -THREE.Line.prototype = Object.create( THREE.Object3D.prototype ); + if (interpolant === null) { + interpolant = mixer._lendControlInterpolant(); + this._timeScaleInterpolant = interpolant; + } -THREE.Line.prototype.clone = function ( object ) { + var times = interpolant.parameterPositions, + values = interpolant.sampleValues; + times[0] = now; + times[1] = now + duration; + values[0] = startTimeScale / timeScale; + values[1] = endTimeScale / timeScale; + return this; + }; - if ( object === undefined ) object = new THREE.Line( this.geometry, this.material, this.type ); + _proto.stopWarping = function stopWarping() { + var timeScaleInterpolant = this._timeScaleInterpolant; - THREE.Object3D.prototype.clone.call( this, object ); + if (timeScaleInterpolant !== null) { + this._timeScaleInterpolant = null; - return object; + this._mixer._takeBackControlInterpolant(timeScaleInterpolant); + } -}; + return this; + } // Object Accessors + ; -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author mikael emtinger / http://gomo.se/ - * @author jonobr1 / http://jonobr1.com/ - */ + _proto.getMixer = function getMixer() { + return this._mixer; + }; -THREE.Mesh = function ( geometry, material ) { + _proto.getClip = function getClip() { + return this._clip; + }; - THREE.Object3D.call( this ); + _proto.getRoot = function getRoot() { + return this._localRoot || this._mixer._root; + } // Interna + ; - this.geometry = geometry !== undefined ? geometry : new THREE.Geometry(); - this.material = material !== undefined ? material : new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ); + _proto._update = function _update(time, deltaTime, timeDirection, accuIndex) { + // called by the mixer + if (!this.enabled) { + // call ._updateWeight() to update ._effectiveWeight + this._updateWeight(time); - this.updateMorphTargets(); + return; + } -}; + var startTime = this._startTime; -THREE.Mesh.prototype = Object.create( THREE.Object3D.prototype ); + if (startTime !== null) { + // check for scheduled start of action + var timeRunning = (time - startTime) * timeDirection; -THREE.Mesh.prototype.updateMorphTargets = function () { + if (timeRunning < 0 || timeDirection === 0) { + return; // yet to come / don't decide when delta = 0 + } // start - if ( this.geometry.morphTargets !== undefined && this.geometry.morphTargets.length > 0 ) { - this.morphTargetBase = -1; - this.morphTargetForcedOrder = []; - this.morphTargetInfluences = []; - this.morphTargetDictionary = {}; + this._startTime = null; // unschedule - for ( var m = 0, ml = this.geometry.morphTargets.length; m < ml; m ++ ) { + deltaTime = timeDirection * timeRunning; + } // apply time scale and advance time - this.morphTargetInfluences.push( 0 ); - this.morphTargetDictionary[ this.geometry.morphTargets[ m ].name ] = m; - } + deltaTime *= this._updateTimeScale(time); - } + var clipTime = this._updateTime(deltaTime); // note: _updateTime may disable the action resulting in + // an effective weight of 0 -}; -THREE.Mesh.prototype.getMorphTargetIndexByName = function ( name ) { + var weight = this._updateWeight(time); - if ( this.morphTargetDictionary[ name ] !== undefined ) { + if (weight > 0) { + var _interpolants = this._interpolants; + var propertyMixers = this._propertyBindings; - return this.morphTargetDictionary[ name ]; + switch (this.blendMode) { + case AdditiveAnimationBlendMode: + for (var j = 0, m = _interpolants.length; j !== m; ++j) { + _interpolants[j].evaluate(clipTime); - } + propertyMixers[j].accumulateAdditive(weight); + } - console.log( "THREE.Mesh.getMorphTargetIndexByName: morph target " + name + " does not exist. Returning 0." ); + break; - return 0; + case NormalAnimationBlendMode: + default: + for (var _j = 0, _m = _interpolants.length; _j !== _m; ++_j) { + _interpolants[_j].evaluate(clipTime); -}; + propertyMixers[_j].accumulate(accuIndex, weight); + } -THREE.Mesh.prototype.clone = function ( object, recursive ) { + } + } + }; - if ( object === undefined ) object = new THREE.Mesh( this.geometry, this.material ); + _proto._updateWeight = function _updateWeight(time) { + var weight = 0; - THREE.Object3D.prototype.clone.call( this, object, recursive ); + if (this.enabled) { + weight = this.weight; + var interpolant = this._weightInterpolant; - return object; + if (interpolant !== null) { + var interpolantValue = interpolant.evaluate(time)[0]; + weight *= interpolantValue; -}; + if (time > interpolant.parameterPositions[1]) { + this.stopFading(); -/** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - */ + if (interpolantValue === 0) { + // faded out, disable + this.enabled = false; + } + } + } + } -THREE.Bone = function( belongsToSkin ) { + this._effectiveWeight = weight; + return weight; + }; - THREE.Object3D.call( this ); + _proto._updateTimeScale = function _updateTimeScale(time) { + var timeScale = 0; - this.skin = belongsToSkin; - this.skinMatrix = new THREE.Matrix4(); + if (!this.paused) { + timeScale = this.timeScale; + var interpolant = this._timeScaleInterpolant; - this.accumulatedRotWeight = 0; - this.accumulatedPosWeight = 0; - this.accumulatedSclWeight = 0; + if (interpolant !== null) { + var interpolantValue = interpolant.evaluate(time)[0]; + timeScale *= interpolantValue; -}; + if (time > interpolant.parameterPositions[1]) { + this.stopWarping(); -THREE.Bone.prototype = Object.create( THREE.Object3D.prototype ); + if (timeScale === 0) { + // motion has halted, pause + this.paused = true; + } else { + // warp done - apply final time scale + this.timeScale = timeScale; + } + } + } + } -THREE.Bone.prototype.update = function ( parentSkinMatrix, forceUpdate ) { + this._effectiveTimeScale = timeScale; + return timeScale; + }; - // update local + _proto._updateTime = function _updateTime(deltaTime) { + var duration = this._clip.duration; + var loop = this.loop; + var time = this.time + deltaTime; + var loopCount = this._loopCount; + var pingPong = loop === LoopPingPong; - if ( this.matrixAutoUpdate ) { + if (deltaTime === 0) { + if (loopCount === -1) return time; + return pingPong && (loopCount & 1) === 1 ? duration - time : time; + } - forceUpdate |= this.updateMatrix(); + if (loop === LoopOnce) { + if (loopCount === -1) { + // just started + this._loopCount = 0; - } + this._setEndings(true, true, false); + } - // update skin matrix + handle_stop: { + if (time >= duration) { + time = duration; + } else if (time < 0) { + time = 0; + } else { + this.time = time; + break handle_stop; + } - if ( forceUpdate || this.matrixWorldNeedsUpdate ) { + if (this.clampWhenFinished) this.paused = true;else this.enabled = false; + this.time = time; - if ( parentSkinMatrix ) { + this._mixer.dispatchEvent({ + type: 'finished', + action: this, + direction: deltaTime < 0 ? -1 : 1 + }); + } + } else { + // repetitive Repeat or PingPong + if (loopCount === -1) { + // just started + if (deltaTime >= 0) { + loopCount = 0; - this.skinMatrix.multiplyMatrices( parentSkinMatrix, this.matrix ); + this._setEndings(true, this.repetitions === 0, pingPong); + } else { + // when looping in reverse direction, the initial + // transition through zero counts as a repetition, + // so leave loopCount at -1 + this._setEndings(this.repetitions === 0, true, pingPong); + } + } - } else { + if (time >= duration || time < 0) { + // wrap around + var loopDelta = Math.floor(time / duration); // signed + + time -= duration * loopDelta; + loopCount += Math.abs(loopDelta); + var pending = this.repetitions - loopCount; + + if (pending <= 0) { + // have to stop (switch state, clamp time, fire event) + if (this.clampWhenFinished) this.paused = true;else this.enabled = false; + time = deltaTime > 0 ? duration : 0; + this.time = time; + + this._mixer.dispatchEvent({ + type: 'finished', + action: this, + direction: deltaTime > 0 ? 1 : -1 + }); + } else { + // keep running + if (pending === 1) { + // entering the last round + var atStart = deltaTime < 0; - this.skinMatrix.copy( this.matrix ); + this._setEndings(atStart, !atStart, pingPong); + } else { + this._setEndings(false, false, pingPong); + } - } + this._loopCount = loopCount; + this.time = time; - this.matrixWorldNeedsUpdate = false; - forceUpdate = true; + this._mixer.dispatchEvent({ + type: 'loop', + action: this, + loopDelta: loopDelta + }); + } + } else { + this.time = time; + } - // Reset weights to be re-accumulated in the next frame + if (pingPong && (loopCount & 1) === 1) { + // invert time for the "pong round" + return duration - time; + } + } - this.accumulatedRotWeight = 0; - this.accumulatedPosWeight = 0; - this.accumulatedSclWeight = 0; + return time; + }; - } + _proto._setEndings = function _setEndings(atStart, atEnd, pingPong) { + var settings = this._interpolantSettings; - // update children + if (pingPong) { + settings.endingStart = ZeroSlopeEnding; + settings.endingEnd = ZeroSlopeEnding; + } else { + // assuming for LoopOnce atStart == atEnd == true + if (atStart) { + settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding; + } else { + settings.endingStart = WrapAroundEnding; + } - for ( var i = 0, l = this.children.length; i < l; i ++ ) { + if (atEnd) { + settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; + } else { + settings.endingEnd = WrapAroundEnding; + } + } + }; - this.children[ i ].update( this.skinMatrix, forceUpdate ); + _proto._scheduleFading = function _scheduleFading(duration, weightNow, weightThen) { + var mixer = this._mixer, + now = mixer.time; + var interpolant = this._weightInterpolant; - } + if (interpolant === null) { + interpolant = mixer._lendControlInterpolant(); + this._weightInterpolant = interpolant; + } -}; + var times = interpolant.parameterPositions, + values = interpolant.sampleValues; + times[0] = now; + values[0] = weightNow; + times[1] = now + duration; + values[1] = weightThen; + return this; + }; + return AnimationAction; + }(); -/** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - * @author michael guerrero / http://realitymeltdown.com - */ + function AnimationMixer(root) { + this._root = root; -THREE.Skeleton = function ( boneList, useVertexTexture ) { + this._initMemoryManager(); - this.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true; + this._accuIndex = 0; + this.time = 0; + this.timeScale = 1.0; + } - // init bones + AnimationMixer.prototype = Object.assign(Object.create(EventDispatcher.prototype), { + constructor: AnimationMixer, + _bindAction: function _bindAction(action, prototypeAction) { + var root = action._localRoot || this._root, + tracks = action._clip.tracks, + nTracks = tracks.length, + bindings = action._propertyBindings, + interpolants = action._interpolants, + rootUuid = root.uuid, + bindingsByRoot = this._bindingsByRootAndName; + var bindingsByName = bindingsByRoot[rootUuid]; - this.bones = []; - this.boneMatrices = []; + if (bindingsByName === undefined) { + bindingsByName = {}; + bindingsByRoot[rootUuid] = bindingsByName; + } - var bone, gbone, p, q, s; + for (var i = 0; i !== nTracks; ++i) { + var track = tracks[i], + trackName = track.name; + var binding = bindingsByName[trackName]; - if ( boneList !== undefined ) { + if (binding !== undefined) { + bindings[i] = binding; + } else { + binding = bindings[i]; - for ( var b = 0; b < boneList.length; ++b ) { + if (binding !== undefined) { + // existing binding, make sure the cache knows + if (binding._cacheIndex === null) { + ++binding.referenceCount; - gbone = boneList[ b ]; + this._addInactiveBinding(binding, rootUuid, trackName); + } - p = gbone.pos; - q = gbone.rotq; - s = gbone.scl; + continue; + } - bone = this.addBone(); + var path = prototypeAction && prototypeAction._propertyBindings[i].binding.parsedPath; + binding = new PropertyMixer(PropertyBinding.create(root, trackName, path), track.ValueTypeName, track.getValueSize()); + ++binding.referenceCount; - bone.name = gbone.name; - bone.position.set( p[0], p[1], p[2] ); - bone.quaternion.set( q[0], q[1], q[2], q[3] ); + this._addInactiveBinding(binding, rootUuid, trackName); - if ( s !== undefined ) { + bindings[i] = binding; + } - bone.scale.set( s[0], s[1], s[2] ); + interpolants[i].resultBuffer = binding.buffer; + } + }, + _activateAction: function _activateAction(action) { + if (!this._isActiveAction(action)) { + if (action._cacheIndex === null) { + // this action has been forgotten by the cache, but the user + // appears to be still using it -> rebind + var rootUuid = (action._localRoot || this._root).uuid, + clipUuid = action._clip.uuid, + actionsForClip = this._actionsByClip[clipUuid]; + + this._bindAction(action, actionsForClip && actionsForClip.knownActions[0]); + + this._addInactiveAction(action, clipUuid, rootUuid); + } - } else { + var bindings = action._propertyBindings; // increment reference counts / sort out state - bone.scale.set( 1, 1, 1 ); + for (var i = 0, n = bindings.length; i !== n; ++i) { + var binding = bindings[i]; - } + if (binding.useCount++ === 0) { + this._lendBinding(binding); - } + binding.saveOriginalState(); + } + } - for ( var b = 0; b < boneList.length; ++b ) { + this._lendAction(action); + } + }, + _deactivateAction: function _deactivateAction(action) { + if (this._isActiveAction(action)) { + var bindings = action._propertyBindings; // decrement reference counts / sort out state - gbone = boneList[ b ]; + for (var i = 0, n = bindings.length; i !== n; ++i) { + var binding = bindings[i]; - if ( gbone.parent !== -1 ) { + if (--binding.useCount === 0) { + binding.restoreOriginalState(); - this.bones[ gbone.parent ].add( this.bones[ b ] ); + this._takeBackBinding(binding); + } + } + this._takeBackAction(action); } + }, + // Memory manager + _initMemoryManager: function _initMemoryManager() { + this._actions = []; // 'nActiveActions' followed by inactive ones - } + this._nActiveActions = 0; + this._actionsByClip = {}; // inside: + // { + // knownActions: Array< AnimationAction > - used as prototypes + // actionByRoot: AnimationAction - lookup + // } - // + this._bindings = []; // 'nActiveBindings' followed by inactive ones - var nBones = this.bones.length; + this._nActiveBindings = 0; + this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > - if ( this.useVertexTexture ) { + this._controlInterpolants = []; // same game as above - // layout (1 matrix = 4 pixels) - // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4) - // with 8x8 pixel texture max 16 bones (8 * 8 / 4) - // 16x16 pixel texture max 64 bones (16 * 16 / 4) - // 32x32 pixel texture max 256 bones (32 * 32 / 4) - // 64x64 pixel texture max 1024 bones (64 * 64 / 4) + this._nActiveControlInterpolants = 0; + var scope = this; + this.stats = { + actions: { + get total() { + return scope._actions.length; + }, + + get inUse() { + return scope._nActiveActions; + } - var size; + }, + bindings: { + get total() { + return scope._bindings.length; + }, - if ( nBones > 256 ) - size = 64; - else if ( nBones > 64 ) - size = 32; - else if ( nBones > 16 ) - size = 16; - else - size = 8; + get inUse() { + return scope._nActiveBindings; + } - this.boneTextureWidth = size; - this.boneTextureHeight = size; + }, + controlInterpolants: { + get total() { + return scope._controlInterpolants.length; + }, - this.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel - this.boneTexture = new THREE.DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, THREE.RGBAFormat, THREE.FloatType ); - this.boneTexture.minFilter = THREE.NearestFilter; - this.boneTexture.magFilter = THREE.NearestFilter; - this.boneTexture.generateMipmaps = false; - this.boneTexture.flipY = false; + get inUse() { + return scope._nActiveControlInterpolants; + } - } else { + } + }; + }, + // Memory management for AnimationAction objects + _isActiveAction: function _isActiveAction(action) { + var index = action._cacheIndex; + return index !== null && index < this._nActiveActions; + }, + _addInactiveAction: function _addInactiveAction(action, clipUuid, rootUuid) { + var actions = this._actions, + actionsByClip = this._actionsByClip; + var actionsForClip = actionsByClip[clipUuid]; + + if (actionsForClip === undefined) { + actionsForClip = { + knownActions: [action], + actionByRoot: {} + }; + action._byClipCacheIndex = 0; + actionsByClip[clipUuid] = actionsForClip; + } else { + var knownActions = actionsForClip.knownActions; + action._byClipCacheIndex = knownActions.length; + knownActions.push(action); + } - this.boneMatrices = new Float32Array( 16 * nBones ); + action._cacheIndex = actions.length; + actions.push(action); + actionsForClip.actionByRoot[rootUuid] = action; + }, + _removeInactiveAction: function _removeInactiveAction(action) { + var actions = this._actions, + lastInactiveAction = actions[actions.length - 1], + cacheIndex = action._cacheIndex; + lastInactiveAction._cacheIndex = cacheIndex; + actions[cacheIndex] = lastInactiveAction; + actions.pop(); + action._cacheIndex = null; + var clipUuid = action._clip.uuid, + actionsByClip = this._actionsByClip, + actionsForClip = actionsByClip[clipUuid], + knownActionsForClip = actionsForClip.knownActions, + lastKnownAction = knownActionsForClip[knownActionsForClip.length - 1], + byClipCacheIndex = action._byClipCacheIndex; + lastKnownAction._byClipCacheIndex = byClipCacheIndex; + knownActionsForClip[byClipCacheIndex] = lastKnownAction; + knownActionsForClip.pop(); + action._byClipCacheIndex = null; + var actionByRoot = actionsForClip.actionByRoot, + rootUuid = (action._localRoot || this._root).uuid; + delete actionByRoot[rootUuid]; + + if (knownActionsForClip.length === 0) { + delete actionsByClip[clipUuid]; + } + + this._removeInactiveBindingsForAction(action); + }, + _removeInactiveBindingsForAction: function _removeInactiveBindingsForAction(action) { + var bindings = action._propertyBindings; - } + for (var i = 0, n = bindings.length; i !== n; ++i) { + var binding = bindings[i]; - } + if (--binding.referenceCount === 0) { + this._removeInactiveBinding(binding); + } + } + }, + _lendAction: function _lendAction(action) { + // [ active actions | inactive actions ] + // [ active actions >| inactive actions ] + // s a + // <-swap-> + // a s + var actions = this._actions, + prevIndex = action._cacheIndex, + lastActiveIndex = this._nActiveActions++, + firstInactiveAction = actions[lastActiveIndex]; + action._cacheIndex = lastActiveIndex; + actions[lastActiveIndex] = action; + firstInactiveAction._cacheIndex = prevIndex; + actions[prevIndex] = firstInactiveAction; + }, + _takeBackAction: function _takeBackAction(action) { + // [ active actions | inactive actions ] + // [ active actions |< inactive actions ] + // a s + // <-swap-> + // s a + var actions = this._actions, + prevIndex = action._cacheIndex, + firstInactiveIndex = --this._nActiveActions, + lastActiveAction = actions[firstInactiveIndex]; + action._cacheIndex = firstInactiveIndex; + actions[firstInactiveIndex] = action; + lastActiveAction._cacheIndex = prevIndex; + actions[prevIndex] = lastActiveAction; + }, + // Memory management for PropertyMixer objects + _addInactiveBinding: function _addInactiveBinding(binding, rootUuid, trackName) { + var bindingsByRoot = this._bindingsByRootAndName, + bindings = this._bindings; + var bindingByName = bindingsByRoot[rootUuid]; -}; + if (bindingByName === undefined) { + bindingByName = {}; + bindingsByRoot[rootUuid] = bindingByName; + } + bindingByName[trackName] = binding; + binding._cacheIndex = bindings.length; + bindings.push(binding); + }, + _removeInactiveBinding: function _removeInactiveBinding(binding) { + var bindings = this._bindings, + propBinding = binding.binding, + rootUuid = propBinding.rootNode.uuid, + trackName = propBinding.path, + bindingsByRoot = this._bindingsByRootAndName, + bindingByName = bindingsByRoot[rootUuid], + lastInactiveBinding = bindings[bindings.length - 1], + cacheIndex = binding._cacheIndex; + lastInactiveBinding._cacheIndex = cacheIndex; + bindings[cacheIndex] = lastInactiveBinding; + bindings.pop(); + delete bindingByName[trackName]; + + if (Object.keys(bindingByName).length === 0) { + delete bindingsByRoot[rootUuid]; + } + }, + _lendBinding: function _lendBinding(binding) { + var bindings = this._bindings, + prevIndex = binding._cacheIndex, + lastActiveIndex = this._nActiveBindings++, + firstInactiveBinding = bindings[lastActiveIndex]; + binding._cacheIndex = lastActiveIndex; + bindings[lastActiveIndex] = binding; + firstInactiveBinding._cacheIndex = prevIndex; + bindings[prevIndex] = firstInactiveBinding; + }, + _takeBackBinding: function _takeBackBinding(binding) { + var bindings = this._bindings, + prevIndex = binding._cacheIndex, + firstInactiveIndex = --this._nActiveBindings, + lastActiveBinding = bindings[firstInactiveIndex]; + binding._cacheIndex = firstInactiveIndex; + bindings[firstInactiveIndex] = binding; + lastActiveBinding._cacheIndex = prevIndex; + bindings[prevIndex] = lastActiveBinding; + }, + // Memory management of Interpolants for weight and time scale + _lendControlInterpolant: function _lendControlInterpolant() { + var interpolants = this._controlInterpolants, + lastActiveIndex = this._nActiveControlInterpolants++; + var interpolant = interpolants[lastActiveIndex]; -THREE.Skeleton.prototype = Object.create( THREE.Mesh.prototype ); + if (interpolant === undefined) { + interpolant = new LinearInterpolant(new Float32Array(2), new Float32Array(2), 1, this._controlInterpolantsResultBuffer); + interpolant.__cacheIndex = lastActiveIndex; + interpolants[lastActiveIndex] = interpolant; + } + return interpolant; + }, + _takeBackControlInterpolant: function _takeBackControlInterpolant(interpolant) { + var interpolants = this._controlInterpolants, + prevIndex = interpolant.__cacheIndex, + firstInactiveIndex = --this._nActiveControlInterpolants, + lastActiveInterpolant = interpolants[firstInactiveIndex]; + interpolant.__cacheIndex = firstInactiveIndex; + interpolants[firstInactiveIndex] = interpolant; + lastActiveInterpolant.__cacheIndex = prevIndex; + interpolants[prevIndex] = lastActiveInterpolant; + }, + _controlInterpolantsResultBuffer: new Float32Array(1), + // return an action for a clip optionally using a custom root target + // object (this method allocates a lot of dynamic memory in case a + // previously unknown clip/root combination is specified) + clipAction: function clipAction(clip, optionalRoot, blendMode) { + var root = optionalRoot || this._root, + rootUuid = root.uuid; + var clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip; + var clipUuid = clipObject !== null ? clipObject.uuid : clip; + var actionsForClip = this._actionsByClip[clipUuid]; + var prototypeAction = null; + + if (blendMode === undefined) { + if (clipObject !== null) { + blendMode = clipObject.blendMode; + } else { + blendMode = NormalAnimationBlendMode; + } + } -THREE.Skeleton.prototype.addBone = function( bone ) { + if (actionsForClip !== undefined) { + var existingAction = actionsForClip.actionByRoot[rootUuid]; - if ( bone === undefined ) { + if (existingAction !== undefined && existingAction.blendMode === blendMode) { + return existingAction; + } // we know the clip, so we don't have to parse all + // the bindings again but can just copy - bone = new THREE.Bone( this ); - } + prototypeAction = actionsForClip.knownActions[0]; // also, take the clip from the prototype action - this.bones.push( bone ); + if (clipObject === null) clipObject = prototypeAction._clip; + } // clip must be known when specified via string - return bone; -}; + if (clipObject === null) return null; // allocate all resources required to run it + var newAction = new AnimationAction(this, clipObject, optionalRoot, blendMode); -THREE.Skeleton.prototype.calculateInverses = function( bone ) { + this._bindAction(newAction, prototypeAction); // and make the action known to the memory manager - this.boneInverses = []; - for ( var b = 0, bl = this.bones.length; b < bl; ++b ) { + this._addInactiveAction(newAction, clipUuid, rootUuid); - var inverse = new THREE.Matrix4(); + return newAction; + }, + // get an existing action + existingAction: function existingAction(clip, optionalRoot) { + var root = optionalRoot || this._root, + rootUuid = root.uuid, + clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip, + clipUuid = clipObject ? clipObject.uuid : clip, + actionsForClip = this._actionsByClip[clipUuid]; - inverse.getInverse( this.bones[ b ].skinMatrix ); + if (actionsForClip !== undefined) { + return actionsForClip.actionByRoot[rootUuid] || null; + } - this.boneInverses.push( inverse ); + return null; + }, + // deactivates all previously scheduled actions + stopAllAction: function stopAllAction() { + var actions = this._actions, + nActions = this._nActiveActions; - } + for (var i = nActions - 1; i >= 0; --i) { + actions[i].stop(); + } -}; - -/** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - */ + return this; + }, + // advance the time and update apply the animation + update: function update(deltaTime) { + deltaTime *= this.timeScale; + var actions = this._actions, + nActions = this._nActiveActions, + time = this.time += deltaTime, + timeDirection = Math.sign(deltaTime), + accuIndex = this._accuIndex ^= 1; // run active actions -THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) { + for (var i = 0; i !== nActions; ++i) { + var action = actions[i]; - THREE.Mesh.call( this, geometry, material ); + action._update(time, deltaTime, timeDirection, accuIndex); + } // update scene graph - this.skeleton = new THREE.Skeleton( this.geometry && this.geometry.bones, useVertexTexture ); - // Add root level bones as children of the mesh + var bindings = this._bindings, + nBindings = this._nActiveBindings; - for ( var b = 0; b < this.skeleton.bones.length; ++b ) { + for (var _i = 0; _i !== nBindings; ++_i) { + bindings[_i].apply(accuIndex); + } - var bone = this.skeleton.bones[ b ]; + return this; + }, + // Allows you to seek to a specific time in an animation. + setTime: function setTime(timeInSeconds) { + this.time = 0; // Zero out time attribute for AnimationMixer object; - if ( bone.parent === undefined ) { + for (var i = 0; i < this._actions.length; i++) { + this._actions[i].time = 0; // Zero out time attribute for all associated AnimationAction objects. + } - this.add( bone ); + return this.update(timeInSeconds); // Update used to set exact time. Returns "this" AnimationMixer object. + }, + // return this mixer's root target object + getRoot: function getRoot() { + return this._root; + }, + // free all resources specific to a particular clip + uncacheClip: function uncacheClip(clip) { + var actions = this._actions, + clipUuid = clip.uuid, + actionsByClip = this._actionsByClip, + actionsForClip = actionsByClip[clipUuid]; + + if (actionsForClip !== undefined) { + // note: just calling _removeInactiveAction would mess up the + // iteration state and also require updating the state we can + // just throw away + var actionsToRemove = actionsForClip.knownActions; + + for (var i = 0, n = actionsToRemove.length; i !== n; ++i) { + var action = actionsToRemove[i]; + + this._deactivateAction(action); + + var cacheIndex = action._cacheIndex, + lastInactiveAction = actions[actions.length - 1]; + action._cacheIndex = null; + action._byClipCacheIndex = null; + lastInactiveAction._cacheIndex = cacheIndex; + actions[cacheIndex] = lastInactiveAction; + actions.pop(); + + this._removeInactiveBindingsForAction(action); + } - } + delete actionsByClip[clipUuid]; + } + }, + // free all resources specific to a particular root target object + uncacheRoot: function uncacheRoot(root) { + var rootUuid = root.uuid, + actionsByClip = this._actionsByClip; - } + for (var clipUuid in actionsByClip) { + var actionByRoot = actionsByClip[clipUuid].actionByRoot, + action = actionByRoot[rootUuid]; - this.identityMatrix = new THREE.Matrix4(); + if (action !== undefined) { + this._deactivateAction(action); - this.pose(); + this._removeInactiveAction(action); + } + } -}; + var bindingsByRoot = this._bindingsByRootAndName, + bindingByName = bindingsByRoot[rootUuid]; + if (bindingByName !== undefined) { + for (var trackName in bindingByName) { + var binding = bindingByName[trackName]; + binding.restoreOriginalState(); -THREE.SkinnedMesh.prototype = Object.create( THREE.Mesh.prototype ); + this._removeInactiveBinding(binding); + } + } + }, + // remove a targeted clip from the cache + uncacheAction: function uncacheAction(clip, optionalRoot) { + var action = this.existingAction(clip, optionalRoot); -THREE.SkinnedMesh.prototype.updateMatrixWorld = function () { + if (action !== null) { + this._deactivateAction(action); - var offsetMatrix = new THREE.Matrix4(); + this._removeInactiveAction(action); + } + } + }); - return function ( force ) { + var Uniform = /*#__PURE__*/function () { + function Uniform(value) { + if (typeof value === 'string') { + console.warn('THREE.Uniform: Type parameter is no longer needed.'); + value = arguments[1]; + } - this.matrixAutoUpdate && this.updateMatrix(); + this.value = value; + } - // update matrixWorld + var _proto = Uniform.prototype; - if ( this.matrixWorldNeedsUpdate || force ) { + _proto.clone = function clone() { + return new Uniform(this.value.clone === undefined ? this.value : this.value.clone()); + }; - if ( this.parent ) { + return Uniform; + }(); - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); + function InstancedInterleavedBuffer(array, stride, meshPerAttribute) { + InterleavedBuffer.call(this, array, stride); + this.meshPerAttribute = meshPerAttribute || 1; + } - } else { + InstancedInterleavedBuffer.prototype = Object.assign(Object.create(InterleavedBuffer.prototype), { + constructor: InstancedInterleavedBuffer, + isInstancedInterleavedBuffer: true, + copy: function copy(source) { + InterleavedBuffer.prototype.copy.call(this, source); + this.meshPerAttribute = source.meshPerAttribute; + return this; + }, + clone: function clone(data) { + var ib = InterleavedBuffer.prototype.clone.call(this, data); + ib.meshPerAttribute = this.meshPerAttribute; + return ib; + }, + toJSON: function toJSON(data) { + var json = InterleavedBuffer.prototype.toJSON.call(this, data); + json.isInstancedInterleavedBuffer = true; + json.meshPerAttribute = this.meshPerAttribute; + return json; + } + }); + + function GLBufferAttribute(buffer, type, itemSize, elementSize, count) { + this.buffer = buffer; + this.type = type; + this.itemSize = itemSize; + this.elementSize = elementSize; + this.count = count; + this.version = 0; + } + + Object.defineProperty(GLBufferAttribute.prototype, 'needsUpdate', { + set: function set(value) { + if (value === true) this.version++; + } + }); + Object.assign(GLBufferAttribute.prototype, { + isGLBufferAttribute: true, + setBuffer: function setBuffer(buffer) { + this.buffer = buffer; + return this; + }, + setType: function setType(type, elementSize) { + this.type = type; + this.elementSize = elementSize; + return this; + }, + setItemSize: function setItemSize(itemSize) { + this.itemSize = itemSize; + return this; + }, + setCount: function setCount(count) { + this.count = count; + return this; + } + }); - this.matrixWorld.copy( this.matrix ); + function Raycaster(origin, direction, near, far) { + this.ray = new Ray(origin, direction); // direction is assumed to be normalized (for accurate distance calculations) + this.near = near || 0; + this.far = far || Infinity; + this.camera = null; + this.layers = new Layers(); + this.params = { + Mesh: {}, + Line: { + threshold: 1 + }, + LOD: {}, + Points: { + threshold: 1 + }, + Sprite: {} + }; + Object.defineProperties(this.params, { + PointCloud: { + get: function get() { + console.warn('THREE.Raycaster: params.PointCloud has been renamed to params.Points.'); + return this.Points; + } } + }); + } - this.matrixWorldNeedsUpdate = false; - - force = true; + function ascSort(a, b) { + return a.distance - b.distance; + } + function _intersectObject(object, raycaster, intersects, recursive) { + if (object.layers.test(raycaster.layers)) { + object.raycast(raycaster, intersects); } - // update children + if (recursive === true) { + var children = object.children; - for ( var i = 0, l = this.children.length; i < l; i ++ ) { - - var child = this.children[ i ]; + for (var i = 0, l = children.length; i < l; i++) { + _intersectObject(children[i], raycaster, intersects, true); + } + } + } - if ( child instanceof THREE.Bone ) { + Object.assign(Raycaster.prototype, { + set: function set(origin, direction) { + // direction is assumed to be normalized (for accurate distance calculations) + this.ray.set(origin, direction); + }, + setFromCamera: function setFromCamera(coords, camera) { + if (camera && camera.isPerspectiveCamera) { + this.ray.origin.setFromMatrixPosition(camera.matrixWorld); + this.ray.direction.set(coords.x, coords.y, 0.5).unproject(camera).sub(this.ray.origin).normalize(); + this.camera = camera; + } else if (camera && camera.isOrthographicCamera) { + this.ray.origin.set(coords.x, coords.y, (camera.near + camera.far) / (camera.near - camera.far)).unproject(camera); // set origin in plane of camera + + this.ray.direction.set(0, 0, -1).transformDirection(camera.matrixWorld); + this.camera = camera; + } else { + console.error('THREE.Raycaster: Unsupported camera type.'); + } + }, + intersectObject: function intersectObject(object, recursive, optionalTarget) { + var intersects = optionalTarget || []; - child.update( this.identityMatrix, false ); + _intersectObject(object, this, intersects, recursive); - } else { + intersects.sort(ascSort); + return intersects; + }, + intersectObjects: function intersectObjects(objects, recursive, optionalTarget) { + var intersects = optionalTarget || []; - child.updateMatrixWorld( true ); + if (Array.isArray(objects) === false) { + console.warn('THREE.Raycaster.intersectObjects: objects is not an Array.'); + return intersects; + } + for (var i = 0, l = objects.length; i < l; i++) { + _intersectObject(objects[i], this, intersects, recursive); } + intersects.sort(ascSort); + return intersects; } + }); - // make a snapshot of the bones' rest position + /** + * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system + * + * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up. + * The azimuthal angle (theta) is measured from the positive z-axis. + */ - if ( this.skeleton.boneInverses === undefined ) { + var Spherical = /*#__PURE__*/function () { + function Spherical(radius, phi, theta) { + if (radius === void 0) { + radius = 1; + } - this.skeleton.calculateInverses(); + if (phi === void 0) { + phi = 0; + } - } + if (theta === void 0) { + theta = 0; + } - // flatten bone matrices to array + this.radius = radius; + this.phi = phi; // polar angle - for ( var b = 0, bl = this.skeleton.bones.length; b < bl; b ++ ) { + this.theta = theta; // azimuthal angle - // compute the offset between the current and the original transform; + return this; + } - // TODO: we could get rid of this multiplication step if the skinMatrix - // was already representing the offset; however, this requires some - // major changes to the animation system + var _proto = Spherical.prototype; - offsetMatrix.multiplyMatrices( this.skeleton.bones[ b ].skinMatrix, this.skeleton.boneInverses[ b ] ); - offsetMatrix.flattenToArrayOffset( this.skeleton.boneMatrices, b * 16 ); + _proto.set = function set(radius, phi, theta) { + this.radius = radius; + this.phi = phi; + this.theta = theta; + return this; + }; - } + _proto.clone = function clone() { + return new this.constructor().copy(this); + }; - if ( this.skeleton.useVertexTexture ) { + _proto.copy = function copy(other) { + this.radius = other.radius; + this.phi = other.phi; + this.theta = other.theta; + return this; + } // restrict phi to be betwee EPS and PI-EPS + ; - this.skeleton.boneTexture.needsUpdate = true; + _proto.makeSafe = function makeSafe() { + var EPS = 0.000001; + this.phi = Math.max(EPS, Math.min(Math.PI - EPS, this.phi)); + return this; + }; - } + _proto.setFromVector3 = function setFromVector3(v) { + return this.setFromCartesianCoords(v.x, v.y, v.z); + }; - }; + _proto.setFromCartesianCoords = function setFromCartesianCoords(x, y, z) { + this.radius = Math.sqrt(x * x + y * y + z * z); -}(); + if (this.radius === 0) { + this.theta = 0; + this.phi = 0; + } else { + this.theta = Math.atan2(x, z); + this.phi = Math.acos(MathUtils.clamp(y / this.radius, -1, 1)); + } -THREE.SkinnedMesh.prototype.pose = function () { + return this; + }; - this.updateMatrixWorld( true ); + return Spherical; + }(); - this.normalizeSkinWeights(); + /** + * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system + */ + var Cylindrical = /*#__PURE__*/function () { + function Cylindrical(radius, theta, y) { + this.radius = radius !== undefined ? radius : 1.0; // distance from the origin to a point in the x-z plane -}; + this.theta = theta !== undefined ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis -THREE.SkinnedMesh.prototype.normalizeSkinWeights = function () { + this.y = y !== undefined ? y : 0; // height above the x-z plane - if ( this.geometry instanceof THREE.Geometry ) { + return this; + } - for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) { + var _proto = Cylindrical.prototype; - var sw = this.geometry.skinWeights[ i ]; + _proto.set = function set(radius, theta, y) { + this.radius = radius; + this.theta = theta; + this.y = y; + return this; + }; - var scale = 1.0 / sw.lengthManhattan(); + _proto.clone = function clone() { + return new this.constructor().copy(this); + }; - if ( scale !== Infinity ) { + _proto.copy = function copy(other) { + this.radius = other.radius; + this.theta = other.theta; + this.y = other.y; + return this; + }; - sw.multiplyScalar( scale ); + _proto.setFromVector3 = function setFromVector3(v) { + return this.setFromCartesianCoords(v.x, v.y, v.z); + }; - } else { + _proto.setFromCartesianCoords = function setFromCartesianCoords(x, y, z) { + this.radius = Math.sqrt(x * x + z * z); + this.theta = Math.atan2(x, z); + this.y = y; + return this; + }; - sw.set( 1 ); // this will be normalized by the shader anyway + return Cylindrical; + }(); - } + var _vector$7 = /*@__PURE__*/new Vector2(); + var Box2 = /*#__PURE__*/function () { + function Box2(min, max) { + Object.defineProperty(this, 'isBox2', { + value: true + }); + this.min = min !== undefined ? min : new Vector2(+Infinity, +Infinity); + this.max = max !== undefined ? max : new Vector2(-Infinity, -Infinity); } - } else { + var _proto = Box2.prototype; - // skinning weights assumed to be normalized for THREE.BufferGeometry + _proto.set = function set(min, max) { + this.min.copy(min); + this.max.copy(max); + return this; + }; - } + _proto.setFromPoints = function setFromPoints(points) { + this.makeEmpty(); -}; + for (var i = 0, il = points.length; i < il; i++) { + this.expandByPoint(points[i]); + } + + return this; + }; -THREE.SkinnedMesh.prototype.clone = function ( object ) { + _proto.setFromCenterAndSize = function setFromCenterAndSize(center, size) { + var halfSize = _vector$7.copy(size).multiplyScalar(0.5); - if ( object === undefined ) { + this.min.copy(center).sub(halfSize); + this.max.copy(center).add(halfSize); + return this; + }; - object = new THREE.SkinnedMesh( this.geometry, this.material, this.useVertexTexture ); + _proto.clone = function clone() { + return new this.constructor().copy(this); + }; - } + _proto.copy = function copy(box) { + this.min.copy(box.min); + this.max.copy(box.max); + return this; + }; - THREE.Mesh.prototype.clone.call( this, object ); + _proto.makeEmpty = function makeEmpty() { + this.min.x = this.min.y = +Infinity; + this.max.x = this.max.y = -Infinity; + return this; + }; - return object; + _proto.isEmpty = function isEmpty() { + // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes + return this.max.x < this.min.x || this.max.y < this.min.y; + }; -}; + _proto.getCenter = function getCenter(target) { + if (target === undefined) { + console.warn('THREE.Box2: .getCenter() target is now required'); + target = new Vector2(); + } -/** - * @author alteredq / http://alteredqualia.com/ - */ + return this.isEmpty() ? target.set(0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); + }; -THREE.MorphAnimMesh = function ( geometry, material ) { + _proto.getSize = function getSize(target) { + if (target === undefined) { + console.warn('THREE.Box2: .getSize() target is now required'); + target = new Vector2(); + } - THREE.Mesh.call( this, geometry, material ); + return this.isEmpty() ? target.set(0, 0) : target.subVectors(this.max, this.min); + }; - // API + _proto.expandByPoint = function expandByPoint(point) { + this.min.min(point); + this.max.max(point); + return this; + }; - this.duration = 1000; // milliseconds - this.mirroredLoop = false; - this.time = 0; + _proto.expandByVector = function expandByVector(vector) { + this.min.sub(vector); + this.max.add(vector); + return this; + }; - // internals + _proto.expandByScalar = function expandByScalar(scalar) { + this.min.addScalar(-scalar); + this.max.addScalar(scalar); + return this; + }; - this.lastKeyframe = 0; - this.currentKeyframe = 0; + _proto.containsPoint = function containsPoint(point) { + return point.x < this.min.x || point.x > this.max.x || point.y < this.min.y || point.y > this.max.y ? false : true; + }; - this.direction = 1; - this.directionBackwards = false; + _proto.containsBox = function containsBox(box) { + return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y; + }; - this.setFrameRange( 0, this.geometry.morphTargets.length - 1 ); + _proto.getParameter = function getParameter(point, target) { + // This can potentially have a divide by zero if the box + // has a size dimension of 0. + if (target === undefined) { + console.warn('THREE.Box2: .getParameter() target is now required'); + target = new Vector2(); + } -}; + return target.set((point.x - this.min.x) / (this.max.x - this.min.x), (point.y - this.min.y) / (this.max.y - this.min.y)); + }; -THREE.MorphAnimMesh.prototype = Object.create( THREE.Mesh.prototype ); + _proto.intersectsBox = function intersectsBox(box) { + // using 4 splitting planes to rule out intersections + return box.max.x < this.min.x || box.min.x > this.max.x || box.max.y < this.min.y || box.min.y > this.max.y ? false : true; + }; -THREE.MorphAnimMesh.prototype.setFrameRange = function ( start, end ) { + _proto.clampPoint = function clampPoint(point, target) { + if (target === undefined) { + console.warn('THREE.Box2: .clampPoint() target is now required'); + target = new Vector2(); + } - this.startKeyframe = start; - this.endKeyframe = end; + return target.copy(point).clamp(this.min, this.max); + }; - this.length = this.endKeyframe - this.startKeyframe + 1; + _proto.distanceToPoint = function distanceToPoint(point) { + var clampedPoint = _vector$7.copy(point).clamp(this.min, this.max); -}; + return clampedPoint.sub(point).length(); + }; -THREE.MorphAnimMesh.prototype.setDirectionForward = function () { + _proto.intersect = function intersect(box) { + this.min.max(box.min); + this.max.min(box.max); + return this; + }; - this.direction = 1; - this.directionBackwards = false; + _proto.union = function union(box) { + this.min.min(box.min); + this.max.max(box.max); + return this; + }; -}; + _proto.translate = function translate(offset) { + this.min.add(offset); + this.max.add(offset); + return this; + }; -THREE.MorphAnimMesh.prototype.setDirectionBackward = function () { + _proto.equals = function equals(box) { + return box.min.equals(this.min) && box.max.equals(this.max); + }; - this.direction = -1; - this.directionBackwards = true; + return Box2; + }(); -}; + var _startP = /*@__PURE__*/new Vector3(); -THREE.MorphAnimMesh.prototype.parseAnimations = function () { + var _startEnd = /*@__PURE__*/new Vector3(); - var geometry = this.geometry; + var Line3 = /*#__PURE__*/function () { + function Line3(start, end) { + this.start = start !== undefined ? start : new Vector3(); + this.end = end !== undefined ? end : new Vector3(); + } - if ( ! geometry.animations ) geometry.animations = {}; + var _proto = Line3.prototype; - var firstAnimation, animations = geometry.animations; + _proto.set = function set(start, end) { + this.start.copy(start); + this.end.copy(end); + return this; + }; - var pattern = /([a-z]+)(\d+)/; + _proto.clone = function clone() { + return new this.constructor().copy(this); + }; - for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) { + _proto.copy = function copy(line) { + this.start.copy(line.start); + this.end.copy(line.end); + return this; + }; - var morph = geometry.morphTargets[ i ]; - var parts = morph.name.match( pattern ); + _proto.getCenter = function getCenter(target) { + if (target === undefined) { + console.warn('THREE.Line3: .getCenter() target is now required'); + target = new Vector3(); + } - if ( parts && parts.length > 1 ) { + return target.addVectors(this.start, this.end).multiplyScalar(0.5); + }; - var label = parts[ 1 ]; - var num = parts[ 2 ]; + _proto.delta = function delta(target) { + if (target === undefined) { + console.warn('THREE.Line3: .delta() target is now required'); + target = new Vector3(); + } - if ( ! animations[ label ] ) animations[ label ] = { start: Infinity, end: -Infinity }; + return target.subVectors(this.end, this.start); + }; - var animation = animations[ label ]; + _proto.distanceSq = function distanceSq() { + return this.start.distanceToSquared(this.end); + }; - if ( i < animation.start ) animation.start = i; - if ( i > animation.end ) animation.end = i; + _proto.distance = function distance() { + return this.start.distanceTo(this.end); + }; - if ( ! firstAnimation ) firstAnimation = label; + _proto.at = function at(t, target) { + if (target === undefined) { + console.warn('THREE.Line3: .at() target is now required'); + target = new Vector3(); + } - } + return this.delta(target).multiplyScalar(t).add(this.start); + }; - } + _proto.closestPointToPointParameter = function closestPointToPointParameter(point, clampToLine) { + _startP.subVectors(point, this.start); - geometry.firstAnimation = firstAnimation; + _startEnd.subVectors(this.end, this.start); -}; + var startEnd2 = _startEnd.dot(_startEnd); -THREE.MorphAnimMesh.prototype.setAnimationLabel = function ( label, start, end ) { + var startEnd_startP = _startEnd.dot(_startP); - if ( ! this.geometry.animations ) this.geometry.animations = {}; + var t = startEnd_startP / startEnd2; - this.geometry.animations[ label ] = { start: start, end: end }; + if (clampToLine) { + t = MathUtils.clamp(t, 0, 1); + } -}; + return t; + }; -THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) { + _proto.closestPointToPoint = function closestPointToPoint(point, clampToLine, target) { + var t = this.closestPointToPointParameter(point, clampToLine); - var animation = this.geometry.animations[ label ]; + if (target === undefined) { + console.warn('THREE.Line3: .closestPointToPoint() target is now required'); + target = new Vector3(); + } - if ( animation ) { + return this.delta(target).multiplyScalar(t).add(this.start); + }; - this.setFrameRange( animation.start, animation.end ); - this.duration = 1000 * ( ( animation.end - animation.start ) / fps ); - this.time = 0; + _proto.applyMatrix4 = function applyMatrix4(matrix) { + this.start.applyMatrix4(matrix); + this.end.applyMatrix4(matrix); + return this; + }; - } else { + _proto.equals = function equals(line) { + return line.start.equals(this.start) && line.end.equals(this.end); + }; - console.warn( "animation[" + label + "] undefined" ); + return Line3; + }(); - } + function ImmediateRenderObject(material) { + Object3D.call(this); + this.material = material; -}; + this.render = function () + /* renderCallback */ + {}; -THREE.MorphAnimMesh.prototype.updateAnimation = function ( delta ) { + this.hasPositions = false; + this.hasNormals = false; + this.hasColors = false; + this.hasUvs = false; + this.positionArray = null; + this.normalArray = null; + this.colorArray = null; + this.uvArray = null; + this.count = 0; + } - var frameTime = this.duration / this.length; + ImmediateRenderObject.prototype = Object.create(Object3D.prototype); + ImmediateRenderObject.prototype.constructor = ImmediateRenderObject; + ImmediateRenderObject.prototype.isImmediateRenderObject = true; - this.time += this.direction * delta; + var _vector$8 = /*@__PURE__*/new Vector3(); - if ( this.mirroredLoop ) { + var SpotLightHelper = /*#__PURE__*/function (_Object3D) { + _inheritsLoose(SpotLightHelper, _Object3D); - if ( this.time > this.duration || this.time < 0 ) { + function SpotLightHelper(light, color) { + var _this; - this.direction *= -1; + _this = _Object3D.call(this) || this; + _this.light = light; - if ( this.time > this.duration ) { + _this.light.updateMatrixWorld(); - this.time = this.duration; - this.directionBackwards = true; + _this.matrix = light.matrixWorld; + _this.matrixAutoUpdate = false; + _this.color = color; + var geometry = new BufferGeometry(); + var positions = [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, -1, 1]; + for (var i = 0, j = 1, l = 32; i < l; i++, j++) { + var p1 = i / l * Math.PI * 2; + var p2 = j / l * Math.PI * 2; + positions.push(Math.cos(p1), Math.sin(p1), 1, Math.cos(p2), Math.sin(p2), 1); } - if ( this.time < 0 ) { + geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); + var material = new LineBasicMaterial({ + fog: false, + toneMapped: false + }); + _this.cone = new LineSegments(geometry, material); - this.time = 0; - this.directionBackwards = false; + _this.add(_this.cone); - } + _this.update(); + return _this; } - } else { + var _proto = SpotLightHelper.prototype; - this.time = this.time % this.duration; + _proto.dispose = function dispose() { + this.cone.geometry.dispose(); + this.cone.material.dispose(); + }; - if ( this.time < 0 ) this.time += this.duration; + _proto.update = function update() { + this.light.updateMatrixWorld(); + var coneLength = this.light.distance ? this.light.distance : 1000; + var coneWidth = coneLength * Math.tan(this.light.angle); + this.cone.scale.set(coneWidth, coneWidth, coneLength); - } + _vector$8.setFromMatrixPosition(this.light.target.matrixWorld); - var keyframe = this.startKeyframe + THREE.Math.clamp( Math.floor( this.time / frameTime ), 0, this.length - 1 ); + this.cone.lookAt(_vector$8); - if ( keyframe !== this.currentKeyframe ) { + if (this.color !== undefined) { + this.cone.material.color.set(this.color); + } else { + this.cone.material.color.copy(this.light.color); + } + }; - this.morphTargetInfluences[ this.lastKeyframe ] = 0; - this.morphTargetInfluences[ this.currentKeyframe ] = 1; + return SpotLightHelper; + }(Object3D); - this.morphTargetInfluences[ keyframe ] = 0; + var _vector$9 = /*@__PURE__*/new Vector3(); - this.lastKeyframe = this.currentKeyframe; - this.currentKeyframe = keyframe; + var _boneMatrix = /*@__PURE__*/new Matrix4(); - } + var _matrixWorldInv = /*@__PURE__*/new Matrix4(); - var mix = ( this.time % frameTime ) / frameTime; + var SkeletonHelper = /*#__PURE__*/function (_LineSegments) { + _inheritsLoose(SkeletonHelper, _LineSegments); - if ( this.directionBackwards ) { + function SkeletonHelper(object) { + var _this; - mix = 1 - mix; + var bones = getBoneList(object); + var geometry = new BufferGeometry(); + var vertices = []; + var colors = []; + var color1 = new Color(0, 0, 1); + var color2 = new Color(0, 1, 0); - } + for (var i = 0; i < bones.length; i++) { + var bone = bones[i]; - this.morphTargetInfluences[ this.currentKeyframe ] = mix; - this.morphTargetInfluences[ this.lastKeyframe ] = 1 - mix; + if (bone.parent && bone.parent.isBone) { + vertices.push(0, 0, 0); + vertices.push(0, 0, 0); + colors.push(color1.r, color1.g, color1.b); + colors.push(color2.r, color2.g, color2.b); + } + } -}; + geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); + geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); + var material = new LineBasicMaterial({ + vertexColors: true, + depthTest: false, + depthWrite: false, + toneMapped: false, + transparent: true + }); + _this = _LineSegments.call(this, geometry, material) || this; + _this.type = 'SkeletonHelper'; + _this.isSkeletonHelper = true; + _this.root = object; + _this.bones = bones; + _this.matrix = object.matrixWorld; + _this.matrixAutoUpdate = false; + return _this; + } -THREE.MorphAnimMesh.prototype.clone = function ( object ) { + var _proto = SkeletonHelper.prototype; - if ( object === undefined ) object = new THREE.MorphAnimMesh( this.geometry, this.material ); + _proto.updateMatrixWorld = function updateMatrixWorld(force) { + var bones = this.bones; + var geometry = this.geometry; + var position = geometry.getAttribute('position'); - object.duration = this.duration; - object.mirroredLoop = this.mirroredLoop; - object.time = this.time; + _matrixWorldInv.getInverse(this.root.matrixWorld); - object.lastKeyframe = this.lastKeyframe; - object.currentKeyframe = this.currentKeyframe; + for (var i = 0, j = 0; i < bones.length; i++) { + var bone = bones[i]; - object.direction = this.direction; - object.directionBackwards = this.directionBackwards; + if (bone.parent && bone.parent.isBone) { + _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.matrixWorld); - THREE.Mesh.prototype.clone.call( this, object ); + _vector$9.setFromMatrixPosition(_boneMatrix); - return object; + position.setXYZ(j, _vector$9.x, _vector$9.y, _vector$9.z); -}; + _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.parent.matrixWorld); -/** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - */ + _vector$9.setFromMatrixPosition(_boneMatrix); -THREE.LOD = function () { + position.setXYZ(j + 1, _vector$9.x, _vector$9.y, _vector$9.z); + j += 2; + } + } - THREE.Object3D.call( this ); + geometry.getAttribute('position').needsUpdate = true; - this.objects = []; + _LineSegments.prototype.updateMatrixWorld.call(this, force); + }; -}; + return SkeletonHelper; + }(LineSegments); + function getBoneList(object) { + var boneList = []; -THREE.LOD.prototype = Object.create( THREE.Object3D.prototype ); + if (object && object.isBone) { + boneList.push(object); + } -THREE.LOD.prototype.addLevel = function ( object, distance ) { + for (var i = 0; i < object.children.length; i++) { + boneList.push.apply(boneList, getBoneList(object.children[i])); + } - if ( distance === undefined ) distance = 0; + return boneList; + } - distance = Math.abs( distance ); + var PointLightHelper = /*#__PURE__*/function (_Mesh) { + _inheritsLoose(PointLightHelper, _Mesh); - for ( var l = 0; l < this.objects.length; l ++ ) { + function PointLightHelper(light, sphereSize, color) { + var _this; - if ( distance < this.objects[ l ].distance ) { + var geometry = new SphereBufferGeometry(sphereSize, 4, 2); + var material = new MeshBasicMaterial({ + wireframe: true, + fog: false, + toneMapped: false + }); + _this = _Mesh.call(this, geometry, material) || this; + _this.light = light; + + _this.light.updateMatrixWorld(); + + _this.color = color; + _this.type = 'PointLightHelper'; + _this.matrix = _this.light.matrixWorld; + _this.matrixAutoUpdate = false; + + _this.update(); + /* + // TODO: delete this comment? + const distanceGeometry = new THREE.IcosahedronBufferGeometry( 1, 2 ); + const distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } ); + this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial ); + this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial ); + const d = light.distance; + if ( d === 0.0 ) { + this.lightDistance.visible = false; + } else { + this.lightDistance.scale.set( d, d, d ); + } + this.add( this.lightDistance ); + */ - break; + return _this; } - } - - this.objects.splice( l, 0, { distance: distance, object: object } ); - this.add( object ); + var _proto = PointLightHelper.prototype; -}; + _proto.dispose = function dispose() { + this.geometry.dispose(); + this.material.dispose(); + }; -THREE.LOD.prototype.getObjectForDistance = function ( distance ) { + _proto.update = function update() { + if (this.color !== undefined) { + this.material.color.set(this.color); + } else { + this.material.color.copy(this.light.color); + } + /* + const d = this.light.distance; + if ( d === 0.0 ) { + this.lightDistance.visible = false; + } else { + this.lightDistance.visible = true; + this.lightDistance.scale.set( d, d, d ); + } + */ - for ( var i = 1, l = this.objects.length; i < l; i ++ ) { + }; - if ( distance < this.objects[ i ].distance ) { + return PointLightHelper; + }(Mesh); - break; + var _vector$a = /*@__PURE__*/new Vector3(); - } + var _color1 = /*@__PURE__*/new Color(); - } + var _color2 = /*@__PURE__*/new Color(); - return this.objects[ i - 1 ].object; + var HemisphereLightHelper = /*#__PURE__*/function (_Object3D) { + _inheritsLoose(HemisphereLightHelper, _Object3D); -}; + function HemisphereLightHelper(light, size, color) { + var _this; -THREE.LOD.prototype.update = function () { + _this = _Object3D.call(this) || this; + _this.light = light; - var v1 = new THREE.Vector3(); - var v2 = new THREE.Vector3(); + _this.light.updateMatrixWorld(); - return function ( camera ) { + _this.matrix = light.matrixWorld; + _this.matrixAutoUpdate = false; + _this.color = color; + var geometry = new OctahedronBufferGeometry(size); + geometry.rotateY(Math.PI * 0.5); + _this.material = new MeshBasicMaterial({ + wireframe: true, + fog: false, + toneMapped: false + }); + if (_this.color === undefined) _this.material.vertexColors = true; + var position = geometry.getAttribute('position'); + var colors = new Float32Array(position.count * 3); + geometry.setAttribute('color', new BufferAttribute(colors, 3)); - if ( this.objects.length > 1 ) { + _this.add(new Mesh(geometry, _this.material)); - v1.setFromMatrixPosition( camera.matrixWorld ); - v2.setFromMatrixPosition( this.matrixWorld ); + _this.update(); - var distance = v1.distanceTo( v2 ); + return _this; + } - this.objects[ 0 ].object.visible = true; + var _proto = HemisphereLightHelper.prototype; - for ( var i = 1, l = this.objects.length; i < l; i ++ ) { + _proto.dispose = function dispose() { + this.children[0].geometry.dispose(); + this.children[0].material.dispose(); + }; - if ( distance >= this.objects[ i ].distance ) { + _proto.update = function update() { + var mesh = this.children[0]; - this.objects[ i - 1 ].object.visible = false; - this.objects[ i ].object.visible = true; + if (this.color !== undefined) { + this.material.color.set(this.color); + } else { + var colors = mesh.geometry.getAttribute('color'); - } else { + _color1.copy(this.light.color); - break; + _color2.copy(this.light.groundColor); + for (var i = 0, l = colors.count; i < l; i++) { + var color = i < l / 2 ? _color1 : _color2; + colors.setXYZ(i, color.r, color.g, color.b); } + colors.needsUpdate = true; } - for( ; i < l; i ++ ) { - - this.objects[ i ].object.visible = false; - - } + mesh.lookAt(_vector$a.setFromMatrixPosition(this.light.matrixWorld).negate()); + }; + return HemisphereLightHelper; + }(Object3D); + + var GridHelper = /*#__PURE__*/function (_LineSegments) { + _inheritsLoose(GridHelper, _LineSegments); + + function GridHelper(size, divisions, color1, color2) { + var _this; + + size = size || 10; + divisions = divisions || 10; + color1 = new Color(color1 !== undefined ? color1 : 0x444444); + color2 = new Color(color2 !== undefined ? color2 : 0x888888); + var center = divisions / 2; + var step = size / divisions; + var halfSize = size / 2; + var vertices = [], + colors = []; + + for (var i = 0, j = 0, k = -halfSize; i <= divisions; i++, k += step) { + vertices.push(-halfSize, 0, k, halfSize, 0, k); + vertices.push(k, 0, -halfSize, k, 0, halfSize); + var color = i === center ? color1 : color2; + color.toArray(colors, j); + j += 3; + color.toArray(colors, j); + j += 3; + color.toArray(colors, j); + j += 3; + color.toArray(colors, j); + j += 3; + } + + var geometry = new BufferGeometry(); + geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); + geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); + var material = new LineBasicMaterial({ + vertexColors: true, + toneMapped: false + }); + _this = _LineSegments.call(this, geometry, material) || this; + _this.type = 'GridHelper'; + return _this; } - }; + return GridHelper; + }(LineSegments); -}(); + var PolarGridHelper = /*#__PURE__*/function (_LineSegments) { + _inheritsLoose(PolarGridHelper, _LineSegments); -THREE.LOD.prototype.clone = function ( object ) { + function PolarGridHelper(radius, radials, circles, divisions, color1, color2) { + var _this; - if ( object === undefined ) object = new THREE.LOD(); + radius = radius || 10; + radials = radials || 16; + circles = circles || 8; + divisions = divisions || 64; + color1 = new Color(color1 !== undefined ? color1 : 0x444444); + color2 = new Color(color2 !== undefined ? color2 : 0x888888); + var vertices = []; + var colors = []; // create the radials - THREE.Object3D.prototype.clone.call( this, object ); + for (var i = 0; i <= radials; i++) { + var v = i / radials * (Math.PI * 2); + var x = Math.sin(v) * radius; + var z = Math.cos(v) * radius; + vertices.push(0, 0, 0); + vertices.push(x, 0, z); + var color = i & 1 ? color1 : color2; + colors.push(color.r, color.g, color.b); + colors.push(color.r, color.g, color.b); + } // create the circles - for ( var i = 0, l = this.objects.length; i < l; i ++ ) { - var x = this.objects[i].object.clone(); - x.visible = i === 0; - object.addLevel( x, this.objects[i].distance ); - } - return object; + for (var _i = 0; _i <= circles; _i++) { + var _color = _i & 1 ? color1 : color2; + + var r = radius - radius / circles * _i; -}; + for (var j = 0; j < divisions; j++) { + // first vertex + var _v = j / divisions * (Math.PI * 2); -/** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - */ + var _x = Math.sin(_v) * r; -THREE.Sprite = ( function () { + var _z = Math.cos(_v) * r; - var vertices = new THREE.Float32Attribute( 3, 3 ); - vertices.set( [ - 0.5, - 0.5, 0, 0.5, - 0.5, 0, 0.5, 0.5, 0 ] ); + vertices.push(_x, 0, _z); + colors.push(_color.r, _color.g, _color.b); // second vertex - var geometry = new THREE.BufferGeometry(); - geometry.addAttribute( 'position', vertices ); + _v = (j + 1) / divisions * (Math.PI * 2); + _x = Math.sin(_v) * r; + _z = Math.cos(_v) * r; + vertices.push(_x, 0, _z); + colors.push(_color.r, _color.g, _color.b); + } + } - return function ( material ) { + var geometry = new BufferGeometry(); + geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); + geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); + var material = new LineBasicMaterial({ + vertexColors: true, + toneMapped: false + }); + _this = _LineSegments.call(this, geometry, material) || this; + _this.type = 'PolarGridHelper'; + return _this; + } - THREE.Object3D.call( this ); + return PolarGridHelper; + }(LineSegments); - this.geometry = geometry; - this.material = ( material !== undefined ) ? material : new THREE.SpriteMaterial(); + var _v1$6 = /*@__PURE__*/new Vector3(); - }; + var _v2$3 = /*@__PURE__*/new Vector3(); -} )(); + var _v3$1 = /*@__PURE__*/new Vector3(); -THREE.Sprite.prototype = Object.create( THREE.Object3D.prototype ); + var DirectionalLightHelper = /*#__PURE__*/function (_Object3D) { + _inheritsLoose(DirectionalLightHelper, _Object3D); -/* - * Custom update matrix - */ + function DirectionalLightHelper(light, size, color) { + var _this; -THREE.Sprite.prototype.updateMatrix = function () { + _this = _Object3D.call(this) || this; + _this.light = light; - this.matrix.compose( this.position, this.quaternion, this.scale ); + _this.light.updateMatrixWorld(); - this.matrixWorldNeedsUpdate = true; + _this.matrix = light.matrixWorld; + _this.matrixAutoUpdate = false; + _this.color = color; + if (size === undefined) size = 1; + var geometry = new BufferGeometry(); + geometry.setAttribute('position', new Float32BufferAttribute([-size, size, 0, size, size, 0, size, -size, 0, -size, -size, 0, -size, size, 0], 3)); + var material = new LineBasicMaterial({ + fog: false, + toneMapped: false + }); + _this.lightPlane = new Line(geometry, material); -}; + _this.add(_this.lightPlane); -THREE.Sprite.prototype.clone = function ( object ) { + geometry = new BufferGeometry(); + geometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 0, 1], 3)); + _this.targetLine = new Line(geometry, material); - if ( object === undefined ) object = new THREE.Sprite( this.material ); + _this.add(_this.targetLine); - THREE.Object3D.prototype.clone.call( this, object ); + _this.update(); - return object; + return _this; + } -}; + var _proto = DirectionalLightHelper.prototype; -// Backwards compatibility + _proto.dispose = function dispose() { + this.lightPlane.geometry.dispose(); + this.lightPlane.material.dispose(); + this.targetLine.geometry.dispose(); + this.targetLine.material.dispose(); + }; -THREE.Particle = THREE.Sprite; -/** - * @author mrdoob / http://mrdoob.com/ - */ + _proto.update = function update() { + _v1$6.setFromMatrixPosition(this.light.matrixWorld); -THREE.Scene = function () { + _v2$3.setFromMatrixPosition(this.light.target.matrixWorld); - THREE.Object3D.call( this ); + _v3$1.subVectors(_v2$3, _v1$6); - this.fog = null; - this.overrideMaterial = null; + this.lightPlane.lookAt(_v2$3); - this.autoUpdate = true; // checked by the renderer - this.matrixAutoUpdate = false; + if (this.color !== undefined) { + this.lightPlane.material.color.set(this.color); + this.targetLine.material.color.set(this.color); + } else { + this.lightPlane.material.color.copy(this.light.color); + this.targetLine.material.color.copy(this.light.color); + } - this.__lights = []; + this.targetLine.lookAt(_v2$3); + this.targetLine.scale.z = _v3$1.length(); + }; - this.__objectsAdded = []; - this.__objectsRemoved = []; + return DirectionalLightHelper; + }(Object3D); -}; + var _vector$b = /*@__PURE__*/new Vector3(); -THREE.Scene.prototype = Object.create( THREE.Object3D.prototype ); + var _camera = /*@__PURE__*/new Camera(); + /** + * - shows frustum, line of sight and up of the camera + * - suitable for fast updates + * - based on frustum visualization in lightgl.js shadowmap example + * http://evanw.github.com/lightgl.js/tests/shadowmap.html + */ -THREE.Scene.prototype.__addObject = function ( object ) { - if ( object instanceof THREE.Light ) { + var CameraHelper = /*#__PURE__*/function (_LineSegments) { + _inheritsLoose(CameraHelper, _LineSegments); - if ( this.__lights.indexOf( object ) === - 1 ) { + function CameraHelper(camera) { + var _this; - this.__lights.push( object ); + var geometry = new BufferGeometry(); + var material = new LineBasicMaterial({ + color: 0xffffff, + vertexColors: true, + toneMapped: false + }); + var vertices = []; + var colors = []; + var pointMap = {}; // colors + + var colorFrustum = new Color(0xffaa00); + var colorCone = new Color(0xff0000); + var colorUp = new Color(0x00aaff); + var colorTarget = new Color(0xffffff); + var colorCross = new Color(0x333333); // near + + addLine('n1', 'n2', colorFrustum); + addLine('n2', 'n4', colorFrustum); + addLine('n4', 'n3', colorFrustum); + addLine('n3', 'n1', colorFrustum); // far + + addLine('f1', 'f2', colorFrustum); + addLine('f2', 'f4', colorFrustum); + addLine('f4', 'f3', colorFrustum); + addLine('f3', 'f1', colorFrustum); // sides + + addLine('n1', 'f1', colorFrustum); + addLine('n2', 'f2', colorFrustum); + addLine('n3', 'f3', colorFrustum); + addLine('n4', 'f4', colorFrustum); // cone + + addLine('p', 'n1', colorCone); + addLine('p', 'n2', colorCone); + addLine('p', 'n3', colorCone); + addLine('p', 'n4', colorCone); // up + + addLine('u1', 'u2', colorUp); + addLine('u2', 'u3', colorUp); + addLine('u3', 'u1', colorUp); // target + + addLine('c', 't', colorTarget); + addLine('p', 'c', colorCross); // cross + + addLine('cn1', 'cn2', colorCross); + addLine('cn3', 'cn4', colorCross); + addLine('cf1', 'cf2', colorCross); + addLine('cf3', 'cf4', colorCross); + + function addLine(a, b, color) { + addPoint(a, color); + addPoint(b, color); + } + + function addPoint(id, color) { + vertices.push(0, 0, 0); + colors.push(color.r, color.g, color.b); + + if (pointMap[id] === undefined) { + pointMap[id] = []; + } - } + pointMap[id].push(vertices.length / 3 - 1); + } - if ( object.target && object.target.parent === undefined ) { + geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); + geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); + _this = _LineSegments.call(this, geometry, material) || this; + _this.type = 'CameraHelper'; + _this.camera = camera; + if (_this.camera.updateProjectionMatrix) _this.camera.updateProjectionMatrix(); + _this.matrix = camera.matrixWorld; + _this.matrixAutoUpdate = false; + _this.pointMap = pointMap; - this.add( object.target ); + _this.update(); + return _this; } - } else if ( !( object instanceof THREE.Camera || object instanceof THREE.Bone ) ) { + var _proto = CameraHelper.prototype; - this.__objectsAdded.push( object ); + _proto.update = function update() { + var geometry = this.geometry; + var pointMap = this.pointMap; + var w = 1, + h = 1; // we need just camera projection matrix inverse + // world matrix must be identity - // check if previously removed + _camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse); // center / target - var i = this.__objectsRemoved.indexOf( object ); - if ( i !== -1 ) { + setPoint('c', pointMap, geometry, _camera, 0, 0, -1); + setPoint('t', pointMap, geometry, _camera, 0, 0, 1); // near - this.__objectsRemoved.splice( i, 1 ); + setPoint('n1', pointMap, geometry, _camera, -w, -h, -1); + setPoint('n2', pointMap, geometry, _camera, w, -h, -1); + setPoint('n3', pointMap, geometry, _camera, -w, h, -1); + setPoint('n4', pointMap, geometry, _camera, w, h, -1); // far - } + setPoint('f1', pointMap, geometry, _camera, -w, -h, 1); + setPoint('f2', pointMap, geometry, _camera, w, -h, 1); + setPoint('f3', pointMap, geometry, _camera, -w, h, 1); + setPoint('f4', pointMap, geometry, _camera, w, h, 1); // up - } + setPoint('u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, -1); + setPoint('u2', pointMap, geometry, _camera, -w * 0.7, h * 1.1, -1); + setPoint('u3', pointMap, geometry, _camera, 0, h * 2, -1); // cross + + setPoint('cf1', pointMap, geometry, _camera, -w, 0, 1); + setPoint('cf2', pointMap, geometry, _camera, w, 0, 1); + setPoint('cf3', pointMap, geometry, _camera, 0, -h, 1); + setPoint('cf4', pointMap, geometry, _camera, 0, h, 1); + setPoint('cn1', pointMap, geometry, _camera, -w, 0, -1); + setPoint('cn2', pointMap, geometry, _camera, w, 0, -1); + setPoint('cn3', pointMap, geometry, _camera, 0, -h, -1); + setPoint('cn4', pointMap, geometry, _camera, 0, h, -1); + geometry.getAttribute('position').needsUpdate = true; + }; - this.dispatchEvent( { type: 'objectAdded', object: object } ); - object.dispatchEvent( { type: 'addedToScene', scene: this } ); + return CameraHelper; + }(LineSegments); - for ( var c = 0; c < object.children.length; c ++ ) { + function setPoint(point, pointMap, geometry, camera, x, y, z) { + _vector$b.set(x, y, z).unproject(camera); - this.__addObject( object.children[ c ] ); + var points = pointMap[point]; + if (points !== undefined) { + var position = geometry.getAttribute('position'); + + for (var i = 0, l = points.length; i < l; i++) { + position.setXYZ(points[i], _vector$b.x, _vector$b.y, _vector$b.z); + } + } } -}; + var _box$3 = /*@__PURE__*/new Box3(); -THREE.Scene.prototype.__removeObject = function ( object ) { + var BoxHelper = /*#__PURE__*/function (_LineSegments) { + _inheritsLoose(BoxHelper, _LineSegments); - if ( object instanceof THREE.Light ) { + function BoxHelper(object, color) { + var _this; - var i = this.__lights.indexOf( object ); + if (color === void 0) { + color = 0xffff00; + } - if ( i !== -1 ) { + var indices = new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]); + var positions = new Float32Array(8 * 3); + var geometry = new BufferGeometry(); + geometry.setIndex(new BufferAttribute(indices, 1)); + geometry.setAttribute('position', new BufferAttribute(positions, 3)); + _this = _LineSegments.call(this, geometry, new LineBasicMaterial({ + color: color, + toneMapped: false + })) || this; + _this.object = object; + _this.type = 'BoxHelper'; + _this.matrixAutoUpdate = false; - this.__lights.splice( i, 1 ); + _this.update(); + return _this; } - if ( object.shadowCascadeArray ) { + var _proto = BoxHelper.prototype; - for ( var x = 0; x < object.shadowCascadeArray.length; x ++ ) { - - this.__removeObject( object.shadowCascadeArray[ x ] ); + _proto.update = function update(object) { + if (object !== undefined) { + console.warn('THREE.BoxHelper: .update() has no longer arguments.'); + } + if (this.object !== undefined) { + _box$3.setFromObject(this.object); } - } + if (_box$3.isEmpty()) return; + var min = _box$3.min; + var max = _box$3.max; + /* + 5____4 + 1/___0/| + | 6__|_7 + 2/___3/ + 0: max.x, max.y, max.z + 1: min.x, max.y, max.z + 2: min.x, min.y, max.z + 3: max.x, min.y, max.z + 4: max.x, max.y, min.z + 5: min.x, max.y, min.z + 6: min.x, min.y, min.z + 7: max.x, min.y, min.z + */ - } else if ( !( object instanceof THREE.Camera ) ) { + var position = this.geometry.attributes.position; + var array = position.array; + array[0] = max.x; + array[1] = max.y; + array[2] = max.z; + array[3] = min.x; + array[4] = max.y; + array[5] = max.z; + array[6] = min.x; + array[7] = min.y; + array[8] = max.z; + array[9] = max.x; + array[10] = min.y; + array[11] = max.z; + array[12] = max.x; + array[13] = max.y; + array[14] = min.z; + array[15] = min.x; + array[16] = max.y; + array[17] = min.z; + array[18] = min.x; + array[19] = min.y; + array[20] = min.z; + array[21] = max.x; + array[22] = min.y; + array[23] = min.z; + position.needsUpdate = true; + this.geometry.computeBoundingSphere(); + }; - this.__objectsRemoved.push( object ); + _proto.setFromObject = function setFromObject(object) { + this.object = object; + this.update(); + return this; + }; - // check if previously added + _proto.copy = function copy(source) { + LineSegments.prototype.copy.call(this, source); + this.object = source.object; + return this; + }; - var i = this.__objectsAdded.indexOf( object ); + return BoxHelper; + }(LineSegments); - if ( i !== -1 ) { + var Box3Helper = /*#__PURE__*/function (_LineSegments) { + _inheritsLoose(Box3Helper, _LineSegments); - this.__objectsAdded.splice( i, 1 ); + function Box3Helper(box, color) { + var _this; - } + if (color === void 0) { + color = 0xffff00; + } - } + var indices = new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]); + var positions = [1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1]; + var geometry = new BufferGeometry(); + geometry.setIndex(new BufferAttribute(indices, 1)); + geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); + _this = _LineSegments.call(this, geometry, new LineBasicMaterial({ + color: color, + toneMapped: false + })) || this; + _this.box = box; + _this.type = 'Box3Helper'; - this.dispatchEvent( { type: 'objectRemoved', object: object } ); - object.dispatchEvent( { type: 'removedFromScene', scene: this } ); + _this.geometry.computeBoundingSphere(); - for ( var c = 0; c < object.children.length; c ++ ) { + return _this; + } - this.__removeObject( object.children[ c ] ); + var _proto = Box3Helper.prototype; - } + _proto.updateMatrixWorld = function updateMatrixWorld(force) { + var box = this.box; + if (box.isEmpty()) return; + box.getCenter(this.position); + box.getSize(this.scale); + this.scale.multiplyScalar(0.5); -}; + _LineSegments.prototype.updateMatrixWorld.call(this, force); + }; -THREE.Scene.prototype.clone = function ( object ) { + return Box3Helper; + }(LineSegments); - if ( object === undefined ) object = new THREE.Scene(); + var PlaneHelper = /*#__PURE__*/function (_Line) { + _inheritsLoose(PlaneHelper, _Line); - THREE.Object3D.prototype.clone.call(this, object); + function PlaneHelper(plane, size, hex) { + var _this; - if ( this.fog !== null ) object.fog = this.fog.clone(); - if ( this.overrideMaterial !== null ) object.overrideMaterial = this.overrideMaterial.clone(); + var color = hex !== undefined ? hex : 0xffff00; + var positions = [1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0]; + var geometry = new BufferGeometry(); + geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); + geometry.computeBoundingSphere(); + _this = _Line.call(this, geometry, new LineBasicMaterial({ + color: color, + toneMapped: false + })) || this; + _this.type = 'PlaneHelper'; + _this.plane = plane; + _this.size = size === undefined ? 1 : size; + var positions2 = [1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1]; + var geometry2 = new BufferGeometry(); + geometry2.setAttribute('position', new Float32BufferAttribute(positions2, 3)); + geometry2.computeBoundingSphere(); - object.autoUpdate = this.autoUpdate; - object.matrixAutoUpdate = this.matrixAutoUpdate; + _this.add(new Mesh(geometry2, new MeshBasicMaterial({ + color: color, + opacity: 0.2, + transparent: true, + depthWrite: false, + toneMapped: false + }))); - return object; - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.Fog = function ( color, near, far ) { - - this.name = ''; - - this.color = new THREE.Color( color ); - - this.near = ( near !== undefined ) ? near : 1; - this.far = ( far !== undefined ) ? far : 1000; - -}; - -THREE.Fog.prototype.clone = function () { - - return new THREE.Fog( this.color.getHex(), this.near, this.far ); + return _this; + } -}; + var _proto = PlaneHelper.prototype; -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + _proto.updateMatrixWorld = function updateMatrixWorld(force) { + var scale = -this.plane.constant; + if (Math.abs(scale) < 1e-8) scale = 1e-8; // sign does not matter -THREE.FogExp2 = function ( color, density ) { + this.scale.set(0.5 * this.size, 0.5 * this.size, scale); + this.children[0].material.side = scale < 0 ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here - this.name = ''; + this.lookAt(this.plane.normal); - this.color = new THREE.Color( color ); - this.density = ( density !== undefined ) ? density : 0.00025; + _Line.prototype.updateMatrixWorld.call(this, force); + }; -}; + return PlaneHelper; + }(Line); -THREE.FogExp2.prototype.clone = function () { + var _axis = /*@__PURE__*/new Vector3(); - return new THREE.FogExp2( this.color.getHex(), this.density ); + var _lineGeometry, _coneGeometry; -}; + var ArrowHelper = /*#__PURE__*/function (_Object3D) { + _inheritsLoose(ArrowHelper, _Object3D); -/** - * @author mrdoob / http://mrdoob.com/ - */ + function ArrowHelper(dir, origin, length, color, headLength, headWidth) { + var _this; -THREE.CanvasRenderer = function ( parameters ) { + _this = _Object3D.call(this) || this; // dir is assumed to be normalized - console.log( 'THREE.CanvasRenderer', THREE.REVISION ); + _this.type = 'ArrowHelper'; + if (dir === undefined) dir = new Vector3(0, 0, 1); + if (origin === undefined) origin = new Vector3(0, 0, 0); + if (length === undefined) length = 1; + if (color === undefined) color = 0xffff00; + if (headLength === undefined) headLength = 0.2 * length; + if (headWidth === undefined) headWidth = 0.2 * headLength; - var smoothstep = THREE.Math.smoothstep; + if (_lineGeometry === undefined) { + _lineGeometry = new BufferGeometry(); - parameters = parameters || {}; + _lineGeometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 1, 0], 3)); - var _this = this, - _renderData, _elements, _lights, - _projector = new THREE.Projector(), + _coneGeometry = new CylinderBufferGeometry(0, 0.5, 1, 5, 1); - _canvas = parameters.canvas !== undefined - ? parameters.canvas - : document.createElement( 'canvas' ), + _coneGeometry.translate(0, -0.5, 0); + } - _canvasWidth = _canvas.width, - _canvasHeight = _canvas.height, - _canvasWidthHalf = Math.floor( _canvasWidth / 2 ), - _canvasHeightHalf = Math.floor( _canvasHeight / 2 ), - - _context = _canvas.getContext( '2d', { - alpha: parameters.alpha === true - } ), + _this.position.copy(origin); - _clearColor = new THREE.Color( 0x000000 ), - _clearAlpha = 0, + _this.line = new Line(_lineGeometry, new LineBasicMaterial({ + color: color, + toneMapped: false + })); + _this.line.matrixAutoUpdate = false; - _contextGlobalAlpha = 1, - _contextGlobalCompositeOperation = 0, - _contextStrokeStyle = null, - _contextFillStyle = null, - _contextLineWidth = null, - _contextLineCap = null, - _contextLineJoin = null, - _contextDashSize = null, - _contextGapSize = 0, + _this.add(_this.line); - _camera, + _this.cone = new Mesh(_coneGeometry, new MeshBasicMaterial({ + color: color, + toneMapped: false + })); + _this.cone.matrixAutoUpdate = false; - _v1, _v2, _v3, _v4, - _v5 = new THREE.RenderableVertex(), - _v6 = new THREE.RenderableVertex(), + _this.add(_this.cone); - _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, - _v4x, _v4y, _v5x, _v5y, _v6x, _v6y, + _this.setDirection(dir); - _color = new THREE.Color(), - _color1 = new THREE.Color(), - _color2 = new THREE.Color(), - _color3 = new THREE.Color(), - _color4 = new THREE.Color(), + _this.setLength(length, headLength, headWidth); - _diffuseColor = new THREE.Color(), - _emissiveColor = new THREE.Color(), + return _this; + } - _lightColor = new THREE.Color(), + var _proto = ArrowHelper.prototype; - _patterns = {}, + _proto.setDirection = function setDirection(dir) { + // dir is assumed to be normalized + if (dir.y > 0.99999) { + this.quaternion.set(0, 0, 0, 1); + } else if (dir.y < -0.99999) { + this.quaternion.set(1, 0, 0, 0); + } else { + _axis.set(dir.z, 0, -dir.x).normalize(); - _image, _uvs, - _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y, + var radians = Math.acos(dir.y); + this.quaternion.setFromAxisAngle(_axis, radians); + } + }; - _clipBox = new THREE.Box2(), - _clearBox = new THREE.Box2(), - _elemBox = new THREE.Box2(), + _proto.setLength = function setLength(length, headLength, headWidth) { + if (headLength === undefined) headLength = 0.2 * length; + if (headWidth === undefined) headWidth = 0.2 * headLength; + this.line.scale.set(1, Math.max(0.0001, length - headLength), 1); // see #17458 - _ambientLight = new THREE.Color(), - _directionalLights = new THREE.Color(), - _pointLights = new THREE.Color(), + this.line.updateMatrix(); + this.cone.scale.set(headWidth, headLength, headWidth); + this.cone.position.y = length; + this.cone.updateMatrix(); + }; - _vector3 = new THREE.Vector3(), // Needed for PointLight - _centroid = new THREE.Vector3(), - _normal = new THREE.Vector3(), - _normalViewMatrix = new THREE.Matrix3(); + _proto.setColor = function setColor(color) { + this.line.material.color.set(color); + this.cone.material.color.set(color); + }; - // dash+gap fallbacks for Firefox and everything else + _proto.copy = function copy(source) { + _Object3D.prototype.copy.call(this, source, false); - if ( _context.setLineDash === undefined ) { + this.line.copy(source.line); + this.cone.copy(source.cone); + return this; + }; - _context.setLineDash = function () {} + return ArrowHelper; + }(Object3D); - } + var AxesHelper = /*#__PURE__*/function (_LineSegments) { + _inheritsLoose(AxesHelper, _LineSegments); - this.domElement = _canvas; + function AxesHelper(size) { + var _this; - this.devicePixelRatio = parameters.devicePixelRatio !== undefined - ? parameters.devicePixelRatio - : self.devicePixelRatio !== undefined - ? self.devicePixelRatio - : 1; + if (size === void 0) { + size = 1; + } - this.autoClear = true; - this.sortObjects = true; - this.sortElements = true; + var vertices = [0, 0, 0, size, 0, 0, 0, 0, 0, 0, size, 0, 0, 0, 0, 0, 0, size]; + var colors = [1, 0, 0, 1, 0.6, 0, 0, 1, 0, 0.6, 1, 0, 0, 0, 1, 0, 0.6, 1]; + var geometry = new BufferGeometry(); + geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); + geometry.setAttribute('color', new Float32BufferAttribute(colors, 3)); + var material = new LineBasicMaterial({ + vertexColors: true, + toneMapped: false + }); + _this = _LineSegments.call(this, geometry, material) || this; + _this.type = 'AxesHelper'; + return _this; + } + + return AxesHelper; + }(LineSegments); + + var _ENCODINGS; + var LOD_MIN = 4; + var LOD_MAX = 8; + var SIZE_MAX = Math.pow(2, LOD_MAX); // The standard deviations (radians) associated with the extra mips. These are + // chosen to approximate a Trowbridge-Reitz distribution function times the + // geometric shadowing function. These sigma values squared must match the + // variance #defines in cube_uv_reflection_fragment.glsl.js. + + var EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; + var TOTAL_LODS = LOD_MAX - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; // The maximum length of the blur for loop. Smaller sigmas will use fewer + // samples and exit early, but not recompile the shader. + + var MAX_SAMPLES = 20; + var ENCODINGS = (_ENCODINGS = {}, _ENCODINGS[LinearEncoding] = 0, _ENCODINGS[sRGBEncoding] = 1, _ENCODINGS[RGBEEncoding] = 2, _ENCODINGS[RGBM7Encoding] = 3, _ENCODINGS[RGBM16Encoding] = 4, _ENCODINGS[RGBDEncoding] = 5, _ENCODINGS[GammaEncoding] = 6, _ENCODINGS); + + var _flatCamera = /*@__PURE__*/new OrthographicCamera(); + + var _createPlanes2 = /*@__PURE__*/_createPlanes(), + _lodPlanes = _createPlanes2._lodPlanes, + _sizeLods = _createPlanes2._sizeLods, + _sigmas = _createPlanes2._sigmas; + + var _oldTarget = null; // Golden Ratio + + var PHI = (1 + Math.sqrt(5)) / 2; + var INV_PHI = 1 / PHI; // Vertices of a dodecahedron (except the opposites, which represent the + // same axis), used as axis directions evenly spread on a sphere. + + var _axisDirections = [/*@__PURE__*/new Vector3(1, 1, 1), /*@__PURE__*/new Vector3(-1, 1, 1), /*@__PURE__*/new Vector3(1, 1, -1), /*@__PURE__*/new Vector3(-1, 1, -1), /*@__PURE__*/new Vector3(0, PHI, INV_PHI), /*@__PURE__*/new Vector3(0, PHI, -INV_PHI), /*@__PURE__*/new Vector3(INV_PHI, 0, PHI), /*@__PURE__*/new Vector3(-INV_PHI, 0, PHI), /*@__PURE__*/new Vector3(PHI, INV_PHI, 0), /*@__PURE__*/new Vector3(-PHI, INV_PHI, 0)]; + /** + * This class generates a Prefiltered, Mipmapped Radiance Environment Map + * (PMREM) from a cubeMap environment texture. This allows different levels of + * blur to be quickly accessed based on material roughness. It is packed into a + * special CubeUV format that allows us to perform custom interpolation so that + * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap + * chain, it only goes down to the LOD_MIN level (above), and then creates extra + * even more filtered 'mips' at the same LOD_MIN resolution, associated with + * higher roughness levels. In this way we maintain resolution to smoothly + * interpolate diffuse lighting while limiting sampling computation. + */ - this.info = { + var PMREMGenerator = /*#__PURE__*/function () { + function PMREMGenerator(renderer) { + this._renderer = renderer; + this._pingPongRenderTarget = null; + this._blurMaterial = _getBlurShader(MAX_SAMPLES); + this._equirectShader = null; + this._cubemapShader = null; - render: { + this._compileMaterial(this._blurMaterial); + } + /** + * Generates a PMREM from a supplied Scene, which can be faster than using an + * image if networking bandwidth is low. Optional sigma specifies a blur radius + * in radians to be applied to the scene before PMREM generation. Optional near + * and far planes ensure the scene is rendered in its entirety (the cubeCamera + * is placed at the origin). + */ - vertices: 0, - faces: 0 - } + var _proto = PMREMGenerator.prototype; - } + _proto.fromScene = function fromScene(scene, sigma, near, far) { + if (sigma === void 0) { + sigma = 0; + } - // WebGLRenderer compatibility + if (near === void 0) { + near = 0.1; + } - this.supportsVertexTextures = function () {}; - this.setFaceCulling = function () {}; + if (far === void 0) { + far = 100; + } - this.setSize = function ( width, height, updateStyle ) { + _oldTarget = this._renderer.getRenderTarget(); - _canvasWidth = width * this.devicePixelRatio; - _canvasHeight = height * this.devicePixelRatio; + var cubeUVRenderTarget = this._allocateTargets(); - _canvas.width = _canvasWidth; - _canvas.height = _canvasHeight; + this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); - _canvasWidthHalf = Math.floor( _canvasWidth / 2 ); - _canvasHeightHalf = Math.floor( _canvasHeight / 2 ); + if (sigma > 0) { + this._blur(cubeUVRenderTarget, 0, 0, sigma); + } - if ( updateStyle !== false ) { + this._applyPMREM(cubeUVRenderTarget); - _canvas.style.width = width + 'px'; - _canvas.style.height = height + 'px'; + this._cleanup(cubeUVRenderTarget); + return cubeUVRenderTarget; } + /** + * Generates a PMREM from an equirectangular texture, which can be either LDR + * (RGBFormat) or HDR (RGBEFormat). The ideal input image size is 1k (1024 x 512), + * as this matches best with the 256 x 256 cubemap output. + */ + ; - _clipBox.min.set( - _canvasWidthHalf, - _canvasHeightHalf ), - _clipBox.max.set( _canvasWidthHalf, _canvasHeightHalf ); + _proto.fromEquirectangular = function fromEquirectangular(equirectangular) { + return this._fromTexture(equirectangular); + } + /** + * Generates a PMREM from an cubemap texture, which can be either LDR + * (RGBFormat) or HDR (RGBEFormat). The ideal input cube size is 256 x 256, + * as this matches best with the 256 x 256 cubemap output. + */ + ; - _clearBox.min.set( - _canvasWidthHalf, - _canvasHeightHalf ); - _clearBox.max.set( _canvasWidthHalf, _canvasHeightHalf ); + _proto.fromCubemap = function fromCubemap(cubemap) { + return this._fromTexture(cubemap); + } + /** + * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + ; - _contextGlobalAlpha = 1; - _contextGlobalCompositeOperation = 0; - _contextStrokeStyle = null; - _contextFillStyle = null; - _contextLineWidth = null; - _contextLineCap = null; - _contextLineJoin = null; + _proto.compileCubemapShader = function compileCubemapShader() { + if (this._cubemapShader === null) { + this._cubemapShader = _getCubemapShader(); - this.setViewport( 0, 0, width, height ); + this._compileMaterial(this._cubemapShader); + } + } + /** + * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + ; - }; + _proto.compileEquirectangularShader = function compileEquirectangularShader() { + if (this._equirectShader === null) { + this._equirectShader = _getEquirectShader(); - this.setViewport = function ( x, y, width, height ) { + this._compileMaterial(this._equirectShader); + } + } + /** + * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, + * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on + * one of them will cause any others to also become unusable. + */ + ; - var viewportX = x * this.devicePixelRatio; - var viewportY = y * this.devicePixelRatio; + _proto.dispose = function dispose() { + this._blurMaterial.dispose(); - var viewportWidth = width * this.devicePixelRatio; - var viewportHeight = height * this.devicePixelRatio; + if (this._cubemapShader !== null) this._cubemapShader.dispose(); + if (this._equirectShader !== null) this._equirectShader.dispose(); - _context.setTransform( viewportWidth / _canvasWidth, 0, 0, - viewportHeight / _canvasHeight, viewportX, _canvasHeight - viewportY ); - _context.translate( _canvasWidthHalf, _canvasHeightHalf ); + for (var i = 0; i < _lodPlanes.length; i++) { + _lodPlanes[i].dispose(); + } + } // private interface + ; - }; + _proto._cleanup = function _cleanup(outputTarget) { + this._pingPongRenderTarget.dispose(); - this.setScissor = function () {}; - this.enableScissorTest = function () {}; + this._renderer.setRenderTarget(_oldTarget); - this.setClearColor = function ( color, alpha ) { + outputTarget.scissorTest = false; - _clearColor.set( color ); - _clearAlpha = alpha !== undefined ? alpha : 1; + _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); + }; - _clearBox.min.set( - _canvasWidthHalf, - _canvasHeightHalf ); - _clearBox.max.set( _canvasWidthHalf, _canvasHeightHalf ); + _proto._fromTexture = function _fromTexture(texture) { + _oldTarget = this._renderer.getRenderTarget(); - }; + var cubeUVRenderTarget = this._allocateTargets(texture); - this.setClearColorHex = function ( hex, alpha ) { + this._textureToCubeUV(texture, cubeUVRenderTarget); - console.warn( 'DEPRECATED: .setClearColorHex() is being removed. Use .setClearColor() instead.' ); - this.setClearColor( hex, alpha ); + this._applyPMREM(cubeUVRenderTarget); - }; + this._cleanup(cubeUVRenderTarget); - this.getMaxAnisotropy = function () { + return cubeUVRenderTarget; + }; - return 0; + _proto._allocateTargets = function _allocateTargets(texture) { + // warning: null texture is valid + var params = { + magFilter: NearestFilter, + minFilter: NearestFilter, + generateMipmaps: false, + type: UnsignedByteType, + format: RGBEFormat, + encoding: _isLDR(texture) ? texture.encoding : RGBEEncoding, + depthBuffer: false + }; - }; + var cubeUVRenderTarget = _createRenderTarget(params); - this.clear = function () { + cubeUVRenderTarget.depthBuffer = texture ? false : true; + this._pingPongRenderTarget = _createRenderTarget(params); + return cubeUVRenderTarget; + }; - if ( _clearBox.empty() === false ) { + _proto._compileMaterial = function _compileMaterial(material) { + var tmpMesh = new Mesh(_lodPlanes[0], material); - _clearBox.intersect( _clipBox ); - _clearBox.expandByScalar( 2 ); + this._renderer.compile(tmpMesh, _flatCamera); + }; - if ( _clearAlpha < 1 ) { + _proto._sceneToCubeUV = function _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { + var fov = 90; + var aspect = 1; + var cubeCamera = new PerspectiveCamera(fov, aspect, near, far); + var upSign = [1, -1, 1, 1, 1, 1]; + var forwardSign = [1, 1, 1, -1, -1, -1]; + var renderer = this._renderer; + var outputEncoding = renderer.outputEncoding; + var toneMapping = renderer.toneMapping; + var clearColor = renderer.getClearColor(); + var clearAlpha = renderer.getClearAlpha(); + renderer.toneMapping = NoToneMapping; + renderer.outputEncoding = LinearEncoding; + var background = scene.background; + + if (background && background.isColor) { + background.convertSRGBToLinear(); // Convert linear to RGBE + + var maxComponent = Math.max(background.r, background.g, background.b); + var fExp = Math.min(Math.max(Math.ceil(Math.log2(maxComponent)), -128.0), 127.0); + background = background.multiplyScalar(Math.pow(2.0, -fExp)); + var alpha = (fExp + 128.0) / 255.0; + renderer.setClearColor(background, alpha); + scene.background = null; + } + + for (var i = 0; i < 6; i++) { + var col = i % 3; + + if (col == 0) { + cubeCamera.up.set(0, upSign[i], 0); + cubeCamera.lookAt(forwardSign[i], 0, 0); + } else if (col == 1) { + cubeCamera.up.set(0, 0, upSign[i]); + cubeCamera.lookAt(0, forwardSign[i], 0); + } else { + cubeCamera.up.set(0, upSign[i], 0); + cubeCamera.lookAt(0, 0, forwardSign[i]); + } - _context.clearRect( - _clearBox.min.x | 0, - _clearBox.min.y | 0, - ( _clearBox.max.x - _clearBox.min.x ) | 0, - ( _clearBox.max.y - _clearBox.min.y ) | 0 - ); + _setViewport(cubeUVRenderTarget, col * SIZE_MAX, i > 2 ? SIZE_MAX : 0, SIZE_MAX, SIZE_MAX); + renderer.setRenderTarget(cubeUVRenderTarget); + renderer.render(scene, cubeCamera); } - if ( _clearAlpha > 0 ) { - - setBlending( THREE.NormalBlending ); - setOpacity( 1 ); - - setFillStyle( 'rgba(' + Math.floor( _clearColor.r * 255 ) + ',' + Math.floor( _clearColor.g * 255 ) + ',' + Math.floor( _clearColor.b * 255 ) + ',' + _clearAlpha + ')' ); + renderer.toneMapping = toneMapping; + renderer.outputEncoding = outputEncoding; + renderer.setClearColor(clearColor, clearAlpha); + }; - _context.fillRect( - _clearBox.min.x | 0, - _clearBox.min.y | 0, - ( _clearBox.max.x - _clearBox.min.x ) | 0, - ( _clearBox.max.y - _clearBox.min.y ) | 0 - ); + _proto._textureToCubeUV = function _textureToCubeUV(texture, cubeUVRenderTarget) { + var renderer = this._renderer; + if (texture.isCubeTexture) { + if (this._cubemapShader == null) { + this._cubemapShader = _getCubemapShader(); + } + } else { + if (this._equirectShader == null) { + this._equirectShader = _getEquirectShader(); + } } - _clearBox.makeEmpty(); + var material = texture.isCubeTexture ? this._cubemapShader : this._equirectShader; + var mesh = new Mesh(_lodPlanes[0], material); + var uniforms = material.uniforms; + uniforms['envMap'].value = texture; - } + if (!texture.isCubeTexture) { + uniforms['texelSize'].value.set(1.0 / texture.image.width, 1.0 / texture.image.height); + } - }; + uniforms['inputEncoding'].value = ENCODINGS[texture.encoding]; + uniforms['outputEncoding'].value = ENCODINGS[cubeUVRenderTarget.texture.encoding]; - // compatibility + _setViewport(cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX); - this.clearColor = function () {}; - this.clearDepth = function () {}; - this.clearStencil = function () {}; + renderer.setRenderTarget(cubeUVRenderTarget); + renderer.render(mesh, _flatCamera); + }; - this.render = function ( scene, camera ) { + _proto._applyPMREM = function _applyPMREM(cubeUVRenderTarget) { + var renderer = this._renderer; + var autoClear = renderer.autoClear; + renderer.autoClear = false; - if ( camera instanceof THREE.Camera === false ) { + for (var i = 1; i < TOTAL_LODS; i++) { + var sigma = Math.sqrt(_sigmas[i] * _sigmas[i] - _sigmas[i - 1] * _sigmas[i - 1]); + var poleAxis = _axisDirections[(i - 1) % _axisDirections.length]; - console.error( 'THREE.CanvasRenderer.render: camera is not an instance of THREE.Camera.' ); - return; + this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); + } + renderer.autoClear = autoClear; } + /** + * This is a two-pass Gaussian blur for a cubemap. Normally this is done + * vertically and horizontally, but this breaks down on a cube. Here we apply + * the blur latitudinally (around the poles), and then longitudinally (towards + * the poles) to approximate the orthogonally-separable blur. It is least + * accurate at the poles, but still does a decent job. + */ + ; - if ( this.autoClear === true ) this.clear(); - - _this.info.render.vertices = 0; - _this.info.render.faces = 0; - - _renderData = _projector.projectScene( scene, camera, this.sortObjects, this.sortElements ); - _elements = _renderData.elements; - _lights = _renderData.lights; - _camera = camera; + _proto._blur = function _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { + var pingPongRenderTarget = this._pingPongRenderTarget; - _normalViewMatrix.getNormalMatrix( camera.matrixWorldInverse ); + this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); - /* DEBUG - setFillStyle( 'rgba( 0, 255, 255, 0.5 )' ); - _context.fillRect( _clipBox.min.x, _clipBox.min.y, _clipBox.max.x - _clipBox.min.x, _clipBox.max.y - _clipBox.min.y ); - */ - - calculateLights(); - - for ( var e = 0, el = _elements.length; e < el; e ++ ) { - - var element = _elements[ e ]; + this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); + }; - var material = element.material; + _proto._halfBlur = function _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { + var renderer = this._renderer; + var blurMaterial = this._blurMaterial; - if ( material === undefined || material.opacity === 0 ) continue; + if (direction !== 'latitudinal' && direction !== 'longitudinal') { + console.error('blur direction must be either latitudinal or longitudinal!'); + } // Number of standard deviations at which to cut off the discrete approximation. - _elemBox.makeEmpty(); - if ( element instanceof THREE.RenderableSprite ) { + var STANDARD_DEVIATIONS = 3; + var blurMesh = new Mesh(_lodPlanes[lodOut], blurMaterial); + var blurUniforms = blurMaterial.uniforms; + var pixels = _sizeLods[lodIn] - 1; + var radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES - 1); + var sigmaPixels = sigmaRadians / radiansPerPixel; + var samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; - _v1 = element; - _v1.x *= _canvasWidthHalf; _v1.y *= _canvasHeightHalf; + if (samples > MAX_SAMPLES) { + console.warn("sigmaRadians, " + sigmaRadians + ", is too large and will clip, as it requested " + samples + " samples when the maximum is set to " + MAX_SAMPLES); + } - renderSprite( _v1, element, material ); + var weights = []; + var sum = 0; - } else if ( element instanceof THREE.RenderableLine ) { + for (var i = 0; i < MAX_SAMPLES; ++i) { + var _x = i / sigmaPixels; - _v1 = element.v1; _v2 = element.v2; + var weight = Math.exp(-_x * _x / 2); + weights.push(weight); - _v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf; - _v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf; + if (i == 0) { + sum += weight; + } else if (i < samples) { + sum += 2 * weight; + } + } - _elemBox.setFromPoints( [ - _v1.positionScreen, - _v2.positionScreen - ] ); + for (var _i = 0; _i < weights.length; _i++) { + weights[_i] = weights[_i] / sum; + } - if ( _clipBox.isIntersectionBox( _elemBox ) === true ) { + blurUniforms['envMap'].value = targetIn.texture; + blurUniforms['samples'].value = samples; + blurUniforms['weights'].value = weights; + blurUniforms['latitudinal'].value = direction === 'latitudinal'; - renderLine( _v1, _v2, element, material ); + if (poleAxis) { + blurUniforms['poleAxis'].value = poleAxis; + } - } + blurUniforms['dTheta'].value = radiansPerPixel; + blurUniforms['mipInt'].value = LOD_MAX - lodIn; + blurUniforms['inputEncoding'].value = ENCODINGS[targetIn.texture.encoding]; + blurUniforms['outputEncoding'].value = ENCODINGS[targetIn.texture.encoding]; + var outputSize = _sizeLods[lodOut]; + var x = 3 * Math.max(0, SIZE_MAX - 2 * outputSize); + var y = (lodOut === 0 ? 0 : 2 * SIZE_MAX) + 2 * outputSize * (lodOut > LOD_MAX - LOD_MIN ? lodOut - LOD_MAX + LOD_MIN : 0); - } else if ( element instanceof THREE.RenderableFace ) { + _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); - _v1 = element.v1; _v2 = element.v2; _v3 = element.v3; + renderer.setRenderTarget(targetOut); + renderer.render(blurMesh, _flatCamera); + }; - if ( _v1.positionScreen.z < -1 || _v1.positionScreen.z > 1 ) continue; - if ( _v2.positionScreen.z < -1 || _v2.positionScreen.z > 1 ) continue; - if ( _v3.positionScreen.z < -1 || _v3.positionScreen.z > 1 ) continue; + return PMREMGenerator; + }(); - _v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf; - _v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf; - _v3.positionScreen.x *= _canvasWidthHalf; _v3.positionScreen.y *= _canvasHeightHalf; + function _isLDR(texture) { + if (texture === undefined || texture.type !== UnsignedByteType) return false; + return texture.encoding === LinearEncoding || texture.encoding === sRGBEncoding || texture.encoding === GammaEncoding; + } - if ( material.overdraw > 0 ) { + function _createPlanes() { + var _lodPlanes = []; + var _sizeLods = []; + var _sigmas = []; + var lod = LOD_MAX; - expand( _v1.positionScreen, _v2.positionScreen, material.overdraw ); - expand( _v2.positionScreen, _v3.positionScreen, material.overdraw ); - expand( _v3.positionScreen, _v1.positionScreen, material.overdraw ); + for (var i = 0; i < TOTAL_LODS; i++) { + var sizeLod = Math.pow(2, lod); - } + _sizeLods.push(sizeLod); - _elemBox.setFromPoints( [ - _v1.positionScreen, - _v2.positionScreen, - _v3.positionScreen - ] ); + var sigma = 1.0 / sizeLod; - if ( _clipBox.isIntersectionBox( _elemBox ) === true ) { + if (i > LOD_MAX - LOD_MIN) { + sigma = EXTRA_LOD_SIGMA[i - LOD_MAX + LOD_MIN - 1]; + } else if (i == 0) { + sigma = 0; + } - renderFace3( _v1, _v2, _v3, 0, 1, 2, element, material ); + _sigmas.push(sigma); - } + var texelSize = 1.0 / (sizeLod - 1); + var min = -texelSize / 2; + var max = 1 + texelSize / 2; + var uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; + var cubeFaces = 6; + var vertices = 6; + var positionSize = 3; + var uvSize = 2; + var faceIndexSize = 1; + var position = new Float32Array(positionSize * vertices * cubeFaces); + var uv = new Float32Array(uvSize * vertices * cubeFaces); + var faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); + for (var face = 0; face < cubeFaces; face++) { + var x = face % 3 * 2 / 3 - 1; + var y = face > 2 ? 0 : -1; + var coordinates = [x, y, 0, x + 2 / 3, y, 0, x + 2 / 3, y + 1, 0, x, y, 0, x + 2 / 3, y + 1, 0, x, y + 1, 0]; + position.set(coordinates, positionSize * vertices * face); + uv.set(uv1, uvSize * vertices * face); + var fill = [face, face, face, face, face, face]; + faceIndex.set(fill, faceIndexSize * vertices * face); } - /* DEBUG - setLineWidth( 1 ); - setStrokeStyle( 'rgba( 0, 255, 0, 0.5 )' ); - _context.strokeRect( _elemBox.min.x, _elemBox.min.y, _elemBox.max.x - _elemBox.min.x, _elemBox.max.y - _elemBox.min.y ); - */ + var planes = new BufferGeometry(); + planes.setAttribute('position', new BufferAttribute(position, positionSize)); + planes.setAttribute('uv', new BufferAttribute(uv, uvSize)); + planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize)); - _clearBox.union( _elemBox ); + _lodPlanes.push(planes); + if (lod > LOD_MIN) { + lod--; + } } - /* DEBUG - setLineWidth( 1 ); - setStrokeStyle( 'rgba( 255, 0, 0, 0.5 )' ); - _context.strokeRect( _clearBox.min.x, _clearBox.min.y, _clearBox.max.x - _clearBox.min.x, _clearBox.max.y - _clearBox.min.y ); - */ + return { + _lodPlanes: _lodPlanes, + _sizeLods: _sizeLods, + _sigmas: _sigmas + }; + } - // _context.setTransform( 1, 0, 0, 1, 0, 0 ); + function _createRenderTarget(params) { + var cubeUVRenderTarget = new WebGLRenderTarget(3 * SIZE_MAX, 3 * SIZE_MAX, params); + cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; + cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; + cubeUVRenderTarget.scissorTest = true; + return cubeUVRenderTarget; + } + + function _setViewport(target, x, y, width, height) { + target.viewport.set(x, y, width, height); + target.scissor.set(x, y, width, height); + } + + function _getBlurShader(maxSamples) { + var weights = new Float32Array(maxSamples); + var poleAxis = new Vector3(0, 1, 0); + var shaderMaterial = new RawShaderMaterial({ + name: 'SphericalGaussianBlur', + defines: { + 'n': maxSamples + }, + uniforms: { + 'envMap': { + value: null + }, + 'samples': { + value: 1 + }, + 'weights': { + value: weights + }, + 'latitudinal': { + value: false + }, + 'dTheta': { + value: 0 + }, + 'mipInt': { + value: 0 + }, + 'poleAxis': { + value: poleAxis + }, + 'inputEncoding': { + value: ENCODINGS[LinearEncoding] + }, + 'outputEncoding': { + value: ENCODINGS[LinearEncoding] + } + }, + vertexShader: _getCommonVertexShader(), + fragmentShader: + /* glsl */ + "\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform int samples;\n\t\t\tuniform float weights[ n ];\n\t\t\tuniform bool latitudinal;\n\t\t\tuniform float dTheta;\n\t\t\tuniform float mipInt;\n\t\t\tuniform vec3 poleAxis;\n\n\t\t\t" + _getEncodings() + "\n\n\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\t\t\t#include \n\n\t\t\tvec3 getSample( float theta, vec3 axis ) {\n\n\t\t\t\tfloat cosTheta = cos( theta );\n\t\t\t\t// Rodrigues' axis-angle rotation\n\t\t\t\tvec3 sampleDirection = vOutputDirection * cosTheta\n\t\t\t\t\t+ cross( axis, vOutputDirection ) * sin( theta )\n\t\t\t\t\t+ axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );\n\n\t\t\t\treturn bilinearCubeUV( envMap, sampleDirection, mipInt );\n\n\t\t\t}\n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );\n\n\t\t\t\tif ( all( equal( axis, vec3( 0.0 ) ) ) ) {\n\n\t\t\t\t\taxis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );\n\n\t\t\t\t}\n\n\t\t\t\taxis = normalize( axis );\n\n\t\t\t\tgl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t\t\t\tgl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );\n\n\t\t\t\tfor ( int i = 1; i < n; i++ ) {\n\n\t\t\t\t\tif ( i >= samples ) {\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfloat theta = dTheta * float( i );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( theta, axis );\n\n\t\t\t\t}\n\n\t\t\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t\t}\n\t\t", + blending: NoBlending, + depthTest: false, + depthWrite: false + }); + return shaderMaterial; + } + + function _getEquirectShader() { + var texelSize = new Vector2(1, 1); + var shaderMaterial = new RawShaderMaterial({ + name: 'EquirectangularToCubeUV', + uniforms: { + 'envMap': { + value: null + }, + 'texelSize': { + value: texelSize + }, + 'inputEncoding': { + value: ENCODINGS[LinearEncoding] + }, + 'outputEncoding': { + value: ENCODINGS[LinearEncoding] + } + }, + vertexShader: _getCommonVertexShader(), + fragmentShader: + /* glsl */ + "\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform vec2 texelSize;\n\n\t\t\t" + _getEncodings() + "\n\n\t\t\t#include \n\n\t\t\tvoid main() {\n\n\t\t\t\tgl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\n\t\t\t\tvec3 outputDirection = normalize( vOutputDirection );\n\t\t\t\tvec2 uv = equirectUv( outputDirection );\n\n\t\t\t\tvec2 f = fract( uv / texelSize - 0.5 );\n\t\t\t\tuv -= f * texelSize;\n\t\t\t\tvec3 tl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;\n\t\t\t\tuv.x += texelSize.x;\n\t\t\t\tvec3 tr = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;\n\t\t\t\tuv.y += texelSize.y;\n\t\t\t\tvec3 br = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;\n\t\t\t\tuv.x -= texelSize.x;\n\t\t\t\tvec3 bl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;\n\n\t\t\t\tvec3 tm = mix( tl, tr, f.x );\n\t\t\t\tvec3 bm = mix( bl, br, f.x );\n\t\t\t\tgl_FragColor.rgb = mix( tm, bm, f.y );\n\n\t\t\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t\t}\n\t\t", + blending: NoBlending, + depthTest: false, + depthWrite: false + }); + return shaderMaterial; + } + + function _getCubemapShader() { + var shaderMaterial = new RawShaderMaterial({ + name: 'CubemapToCubeUV', + uniforms: { + 'envMap': { + value: null + }, + 'inputEncoding': { + value: ENCODINGS[LinearEncoding] + }, + 'outputEncoding': { + value: ENCODINGS[LinearEncoding] + } + }, + vertexShader: _getCommonVertexShader(), + fragmentShader: + /* glsl */ + "\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform samplerCube envMap;\n\n\t\t\t" + _getEncodings() + "\n\n\t\t\tvoid main() {\n\n\t\t\t\tgl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t\t\t\tgl_FragColor.rgb = envMapTexelToLinear( textureCube( envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ) ) ).rgb;\n\t\t\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t\t}\n\t\t", + blending: NoBlending, + depthTest: false, + depthWrite: false + }); + return shaderMaterial; + } + + function _getCommonVertexShader() { + return ( + /* glsl */ + "\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\n\t\tattribute vec3 position;\n\t\tattribute vec2 uv;\n\t\tattribute float faceIndex;\n\n\t\tvarying vec3 vOutputDirection;\n\n\t\t// RH coordinate system; PMREM face-indexing convention\n\t\tvec3 getDirection( vec2 uv, float face ) {\n\n\t\t\tuv = 2.0 * uv - 1.0;\n\n\t\t\tvec3 direction = vec3( uv, 1.0 );\n\n\t\t\tif ( face == 0.0 ) {\n\n\t\t\t\tdirection = direction.zyx; // ( 1, v, u ) pos x\n\n\t\t\t} else if ( face == 1.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xz *= -1.0; // ( -u, 1, -v ) pos y\n\n\t\t\t} else if ( face == 2.0 ) {\n\n\t\t\t\tdirection.x *= -1.0; // ( -u, v, 1 ) pos z\n\n\t\t\t} else if ( face == 3.0 ) {\n\n\t\t\t\tdirection = direction.zyx;\n\t\t\t\tdirection.xz *= -1.0; // ( -1, v, -u ) neg x\n\n\t\t\t} else if ( face == 4.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xy *= -1.0; // ( -u, -1, v ) neg y\n\n\t\t\t} else if ( face == 5.0 ) {\n\n\t\t\t\tdirection.z *= -1.0; // ( u, v, -1 ) neg z\n\n\t\t\t}\n\n\t\t\treturn direction;\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tvOutputDirection = getDirection( uv, faceIndex );\n\t\t\tgl_Position = vec4( position, 1.0 );\n\n\t\t}\n\t" + ); + } - }; + function _getEncodings() { + return ( + /* glsl */ + "\n\n\t\tuniform int inputEncoding;\n\t\tuniform int outputEncoding;\n\n\t\t#include \n\n\t\tvec4 inputTexelToLinear( vec4 value ) {\n\n\t\t\tif ( inputEncoding == 0 ) {\n\n\t\t\t\treturn value;\n\n\t\t\t} else if ( inputEncoding == 1 ) {\n\n\t\t\t\treturn sRGBToLinear( value );\n\n\t\t\t} else if ( inputEncoding == 2 ) {\n\n\t\t\t\treturn RGBEToLinear( value );\n\n\t\t\t} else if ( inputEncoding == 3 ) {\n\n\t\t\t\treturn RGBMToLinear( value, 7.0 );\n\n\t\t\t} else if ( inputEncoding == 4 ) {\n\n\t\t\t\treturn RGBMToLinear( value, 16.0 );\n\n\t\t\t} else if ( inputEncoding == 5 ) {\n\n\t\t\t\treturn RGBDToLinear( value, 256.0 );\n\n\t\t\t} else {\n\n\t\t\t\treturn GammaToLinear( value, 2.2 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvec4 linearToOutputTexel( vec4 value ) {\n\n\t\t\tif ( outputEncoding == 0 ) {\n\n\t\t\t\treturn value;\n\n\t\t\t} else if ( outputEncoding == 1 ) {\n\n\t\t\t\treturn LinearTosRGB( value );\n\n\t\t\t} else if ( outputEncoding == 2 ) {\n\n\t\t\t\treturn LinearToRGBE( value );\n\n\t\t\t} else if ( outputEncoding == 3 ) {\n\n\t\t\t\treturn LinearToRGBM( value, 7.0 );\n\n\t\t\t} else if ( outputEncoding == 4 ) {\n\n\t\t\t\treturn LinearToRGBM( value, 16.0 );\n\n\t\t\t} else if ( outputEncoding == 5 ) {\n\n\t\t\t\treturn LinearToRGBD( value, 256.0 );\n\n\t\t\t} else {\n\n\t\t\t\treturn LinearToGamma( value, 2.2 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvec4 envMapTexelToLinear( vec4 color ) {\n\n\t\t\treturn inputTexelToLinear( color );\n\n\t\t}\n\t" + ); + } - // + function Face4(a, b, c, d, normal, color, materialIndex) { + console.warn('THREE.Face4 has been removed. A THREE.Face3 will be created instead.'); + return new Face3(a, b, c, normal, color, materialIndex); + } + var LineStrip = 0; + var LinePieces = 1; + var NoColors = 0; + var FaceColors = 1; + var VertexColors = 2; + function MeshFaceMaterial(materials) { + console.warn('THREE.MeshFaceMaterial has been removed. Use an Array instead.'); + return materials; + } + function MultiMaterial(materials) { + if (materials === undefined) materials = []; + console.warn('THREE.MultiMaterial has been removed. Use an Array instead.'); + materials.isMultiMaterial = true; + materials.materials = materials; - function calculateLights() { + materials.clone = function () { + return materials.slice(); + }; - _ambientLight.setRGB( 0, 0, 0 ); - _directionalLights.setRGB( 0, 0, 0 ); - _pointLights.setRGB( 0, 0, 0 ); + return materials; + } + function PointCloud(geometry, material) { + console.warn('THREE.PointCloud has been renamed to THREE.Points.'); + return new Points(geometry, material); + } + function Particle(material) { + console.warn('THREE.Particle has been renamed to THREE.Sprite.'); + return new Sprite(material); + } + function ParticleSystem(geometry, material) { + console.warn('THREE.ParticleSystem has been renamed to THREE.Points.'); + return new Points(geometry, material); + } + function PointCloudMaterial(parameters) { + console.warn('THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.'); + return new PointsMaterial(parameters); + } + function ParticleBasicMaterial(parameters) { + console.warn('THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.'); + return new PointsMaterial(parameters); + } + function ParticleSystemMaterial(parameters) { + console.warn('THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.'); + return new PointsMaterial(parameters); + } + function Vertex(x, y, z) { + console.warn('THREE.Vertex has been removed. Use THREE.Vector3 instead.'); + return new Vector3(x, y, z); + } // - for ( var l = 0, ll = _lights.length; l < ll; l ++ ) { + function DynamicBufferAttribute(array, itemSize) { + console.warn('THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setUsage( THREE.DynamicDrawUsage ) instead.'); + return new BufferAttribute(array, itemSize).setUsage(DynamicDrawUsage); + } + function Int8Attribute(array, itemSize) { + console.warn('THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.'); + return new Int8BufferAttribute(array, itemSize); + } + function Uint8Attribute(array, itemSize) { + console.warn('THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.'); + return new Uint8BufferAttribute(array, itemSize); + } + function Uint8ClampedAttribute(array, itemSize) { + console.warn('THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.'); + return new Uint8ClampedBufferAttribute(array, itemSize); + } + function Int16Attribute(array, itemSize) { + console.warn('THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.'); + return new Int16BufferAttribute(array, itemSize); + } + function Uint16Attribute(array, itemSize) { + console.warn('THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.'); + return new Uint16BufferAttribute(array, itemSize); + } + function Int32Attribute(array, itemSize) { + console.warn('THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.'); + return new Int32BufferAttribute(array, itemSize); + } + function Uint32Attribute(array, itemSize) { + console.warn('THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.'); + return new Uint32BufferAttribute(array, itemSize); + } + function Float32Attribute(array, itemSize) { + console.warn('THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.'); + return new Float32BufferAttribute(array, itemSize); + } + function Float64Attribute(array, itemSize) { + console.warn('THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.'); + return new Float64BufferAttribute(array, itemSize); + } // - var light = _lights[ l ]; - var lightColor = light.color; + Curve.create = function (construct, getPoint) { + console.log('THREE.Curve.create() has been deprecated'); + construct.prototype = Object.create(Curve.prototype); + construct.prototype.constructor = construct; + construct.prototype.getPoint = getPoint; + return construct; + }; // - if ( light instanceof THREE.AmbientLight ) { - _ambientLight.add( lightColor ); + Object.assign(CurvePath.prototype, { + createPointsGeometry: function createPointsGeometry(divisions) { + console.warn('THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.'); // generate geometry from path points (for Line or Points objects) - } else if ( light instanceof THREE.DirectionalLight ) { + var pts = this.getPoints(divisions); + return this.createGeometry(pts); + }, + createSpacedPointsGeometry: function createSpacedPointsGeometry(divisions) { + console.warn('THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.'); // generate geometry from equidistant sampling along the path - // for sprites + var pts = this.getSpacedPoints(divisions); + return this.createGeometry(pts); + }, + createGeometry: function createGeometry(points) { + console.warn('THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.'); + var geometry = new Geometry(); - _directionalLights.add( lightColor ); + for (var i = 0, l = points.length; i < l; i++) { + var point = points[i]; + geometry.vertices.push(new Vector3(point.x, point.y, point.z || 0)); + } - } else if ( light instanceof THREE.PointLight ) { + return geometry; + } + }); // - // for sprites + Object.assign(Path.prototype, { + fromPoints: function fromPoints(points) { + console.warn('THREE.Path: .fromPoints() has been renamed to .setFromPoints().'); + return this.setFromPoints(points); + } + }); // - _pointLights.add( lightColor ); + function ClosedSplineCurve3(points) { + console.warn('THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.'); + CatmullRomCurve3.call(this, points); + this.type = 'catmullrom'; + this.closed = true; + } + ClosedSplineCurve3.prototype = Object.create(CatmullRomCurve3.prototype); // - } + function SplineCurve3(points) { + console.warn('THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.'); + CatmullRomCurve3.call(this, points); + this.type = 'catmullrom'; + } + SplineCurve3.prototype = Object.create(CatmullRomCurve3.prototype); // + function Spline(points) { + console.warn('THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.'); + CatmullRomCurve3.call(this, points); + this.type = 'catmullrom'; + } + Spline.prototype = Object.create(CatmullRomCurve3.prototype); + Object.assign(Spline.prototype, { + initFromArray: function initFromArray() + /* a */ + { + console.error('THREE.Spline: .initFromArray() has been removed.'); + }, + getControlPointsArray: function getControlPointsArray() + /* optionalTarget */ + { + console.error('THREE.Spline: .getControlPointsArray() has been removed.'); + }, + reparametrizeByArcLength: function reparametrizeByArcLength() + /* samplingCoef */ + { + console.error('THREE.Spline: .reparametrizeByArcLength() has been removed.'); } + }); // + function AxisHelper(size) { + console.warn('THREE.AxisHelper has been renamed to THREE.AxesHelper.'); + return new AxesHelper(size); + } + function BoundingBoxHelper(object, color) { + console.warn('THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.'); + return new BoxHelper(object, color); + } + function EdgesHelper(object, hex) { + console.warn('THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.'); + return new LineSegments(new EdgesGeometry(object.geometry), new LineBasicMaterial({ + color: hex !== undefined ? hex : 0xffffff + })); } - function calculateLight( position, normal, color ) { - - for ( var l = 0, ll = _lights.length; l < ll; l ++ ) { + GridHelper.prototype.setColors = function () { + console.error('THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.'); + }; - var light = _lights[ l ]; + SkeletonHelper.prototype.update = function () { + console.error('THREE.SkeletonHelper: update() no longer needs to be called.'); + }; - _lightColor.copy( light.color ); + function WireframeHelper(object, hex) { + console.warn('THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.'); + return new LineSegments(new WireframeGeometry(object.geometry), new LineBasicMaterial({ + color: hex !== undefined ? hex : 0xffffff + })); + } // + + Object.assign(Loader.prototype, { + extractUrlBase: function extractUrlBase(url) { + console.warn('THREE.Loader: .extractUrlBase() has been deprecated. Use THREE.LoaderUtils.extractUrlBase() instead.'); + return LoaderUtils.extractUrlBase(url); + } + }); + Loader.Handlers = { + add: function add() + /* regex, loader */ + { + console.error('THREE.Loader: Handlers.add() has been removed. Use LoadingManager.addHandler() instead.'); + }, + get: function get() + /* file */ + { + console.error('THREE.Loader: Handlers.get() has been removed. Use LoadingManager.getHandler() instead.'); + } + }; + function XHRLoader(manager) { + console.warn('THREE.XHRLoader has been renamed to THREE.FileLoader.'); + return new FileLoader(manager); + } + function BinaryTextureLoader(manager) { + console.warn('THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.'); + return new DataTextureLoader(manager); + } // + + Object.assign(Box2.prototype, { + center: function center(optionalTarget) { + console.warn('THREE.Box2: .center() has been renamed to .getCenter().'); + return this.getCenter(optionalTarget); + }, + empty: function empty() { + console.warn('THREE.Box2: .empty() has been renamed to .isEmpty().'); + return this.isEmpty(); + }, + isIntersectionBox: function isIntersectionBox(box) { + console.warn('THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().'); + return this.intersectsBox(box); + }, + size: function size(optionalTarget) { + console.warn('THREE.Box2: .size() has been renamed to .getSize().'); + return this.getSize(optionalTarget); + } + }); + Object.assign(Box3.prototype, { + center: function center(optionalTarget) { + console.warn('THREE.Box3: .center() has been renamed to .getCenter().'); + return this.getCenter(optionalTarget); + }, + empty: function empty() { + console.warn('THREE.Box3: .empty() has been renamed to .isEmpty().'); + return this.isEmpty(); + }, + isIntersectionBox: function isIntersectionBox(box) { + console.warn('THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().'); + return this.intersectsBox(box); + }, + isIntersectionSphere: function isIntersectionSphere(sphere) { + console.warn('THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().'); + return this.intersectsSphere(sphere); + }, + size: function size(optionalTarget) { + console.warn('THREE.Box3: .size() has been renamed to .getSize().'); + return this.getSize(optionalTarget); + } + }); + Object.assign(Sphere.prototype, { + empty: function empty() { + console.warn('THREE.Sphere: .empty() has been renamed to .isEmpty().'); + return this.isEmpty(); + } + }); - if ( light instanceof THREE.DirectionalLight ) { + Frustum.prototype.setFromMatrix = function (m) { + console.warn('THREE.Frustum: .setFromMatrix() has been renamed to .setFromProjectionMatrix().'); + return this.setFromProjectionMatrix(m); + }; - var lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld ).normalize(); + Line3.prototype.center = function (optionalTarget) { + console.warn('THREE.Line3: .center() has been renamed to .getCenter().'); + return this.getCenter(optionalTarget); + }; - var amount = normal.dot( lightPosition ); + Object.assign(MathUtils, { + random16: function random16() { + console.warn('THREE.Math: .random16() has been deprecated. Use Math.random() instead.'); + return Math.random(); + }, + nearestPowerOfTwo: function nearestPowerOfTwo(value) { + console.warn('THREE.Math: .nearestPowerOfTwo() has been renamed to .floorPowerOfTwo().'); + return MathUtils.floorPowerOfTwo(value); + }, + nextPowerOfTwo: function nextPowerOfTwo(value) { + console.warn('THREE.Math: .nextPowerOfTwo() has been renamed to .ceilPowerOfTwo().'); + return MathUtils.ceilPowerOfTwo(value); + } + }); + Object.assign(Matrix3.prototype, { + flattenToArrayOffset: function flattenToArrayOffset(array, offset) { + console.warn("THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead."); + return this.toArray(array, offset); + }, + multiplyVector3: function multiplyVector3(vector) { + console.warn('THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.'); + return vector.applyMatrix3(this); + }, + multiplyVector3Array: function multiplyVector3Array() + /* a */ + { + console.error('THREE.Matrix3: .multiplyVector3Array() has been removed.'); + }, + applyToBufferAttribute: function applyToBufferAttribute(attribute) { + console.warn('THREE.Matrix3: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix3( matrix ) instead.'); + return attribute.applyMatrix3(this); + }, + applyToVector3Array: function applyToVector3Array() + /* array, offset, length */ + { + console.error('THREE.Matrix3: .applyToVector3Array() has been removed.'); + } + }); + Object.assign(Matrix4.prototype, { + extractPosition: function extractPosition(m) { + console.warn('THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().'); + return this.copyPosition(m); + }, + flattenToArrayOffset: function flattenToArrayOffset(array, offset) { + console.warn("THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead."); + return this.toArray(array, offset); + }, + getPosition: function getPosition() { + console.warn('THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.'); + return new Vector3().setFromMatrixColumn(this, 3); + }, + setRotationFromQuaternion: function setRotationFromQuaternion(q) { + console.warn('THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().'); + return this.makeRotationFromQuaternion(q); + }, + multiplyToArray: function multiplyToArray() { + console.warn('THREE.Matrix4: .multiplyToArray() has been removed.'); + }, + multiplyVector3: function multiplyVector3(vector) { + console.warn('THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.'); + return vector.applyMatrix4(this); + }, + multiplyVector4: function multiplyVector4(vector) { + console.warn('THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.'); + return vector.applyMatrix4(this); + }, + multiplyVector3Array: function multiplyVector3Array() + /* a */ + { + console.error('THREE.Matrix4: .multiplyVector3Array() has been removed.'); + }, + rotateAxis: function rotateAxis(v) { + console.warn('THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.'); + v.transformDirection(this); + }, + crossVector: function crossVector(vector) { + console.warn('THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.'); + return vector.applyMatrix4(this); + }, + translate: function translate() { + console.error('THREE.Matrix4: .translate() has been removed.'); + }, + rotateX: function rotateX() { + console.error('THREE.Matrix4: .rotateX() has been removed.'); + }, + rotateY: function rotateY() { + console.error('THREE.Matrix4: .rotateY() has been removed.'); + }, + rotateZ: function rotateZ() { + console.error('THREE.Matrix4: .rotateZ() has been removed.'); + }, + rotateByAxis: function rotateByAxis() { + console.error('THREE.Matrix4: .rotateByAxis() has been removed.'); + }, + applyToBufferAttribute: function applyToBufferAttribute(attribute) { + console.warn('THREE.Matrix4: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix4( matrix ) instead.'); + return attribute.applyMatrix4(this); + }, + applyToVector3Array: function applyToVector3Array() + /* array, offset, length */ + { + console.error('THREE.Matrix4: .applyToVector3Array() has been removed.'); + }, + makeFrustum: function makeFrustum(left, right, bottom, top, near, far) { + console.warn('THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.'); + return this.makePerspective(left, right, top, bottom, near, far); + } + }); - if ( amount <= 0 ) continue; + Plane.prototype.isIntersectionLine = function (line) { + console.warn('THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().'); + return this.intersectsLine(line); + }; - amount *= light.intensity; + Quaternion.prototype.multiplyVector3 = function (vector) { + console.warn('THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.'); + return vector.applyQuaternion(this); + }; - color.add( _lightColor.multiplyScalar( amount ) ); + Object.assign(Ray.prototype, { + isIntersectionBox: function isIntersectionBox(box) { + console.warn('THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().'); + return this.intersectsBox(box); + }, + isIntersectionPlane: function isIntersectionPlane(plane) { + console.warn('THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().'); + return this.intersectsPlane(plane); + }, + isIntersectionSphere: function isIntersectionSphere(sphere) { + console.warn('THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().'); + return this.intersectsSphere(sphere); + } + }); + Object.assign(Triangle.prototype, { + area: function area() { + console.warn('THREE.Triangle: .area() has been renamed to .getArea().'); + return this.getArea(); + }, + barycoordFromPoint: function barycoordFromPoint(point, target) { + console.warn('THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().'); + return this.getBarycoord(point, target); + }, + midpoint: function midpoint(target) { + console.warn('THREE.Triangle: .midpoint() has been renamed to .getMidpoint().'); + return this.getMidpoint(target); + }, + normal: function normal(target) { + console.warn('THREE.Triangle: .normal() has been renamed to .getNormal().'); + return this.getNormal(target); + }, + plane: function plane(target) { + console.warn('THREE.Triangle: .plane() has been renamed to .getPlane().'); + return this.getPlane(target); + } + }); + Object.assign(Triangle, { + barycoordFromPoint: function barycoordFromPoint(point, a, b, c, target) { + console.warn('THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().'); + return Triangle.getBarycoord(point, a, b, c, target); + }, + normal: function normal(a, b, c, target) { + console.warn('THREE.Triangle: .normal() has been renamed to .getNormal().'); + return Triangle.getNormal(a, b, c, target); + } + }); + Object.assign(Shape.prototype, { + extractAllPoints: function extractAllPoints(divisions) { + console.warn('THREE.Shape: .extractAllPoints() has been removed. Use .extractPoints() instead.'); + return this.extractPoints(divisions); + }, + extrude: function extrude(options) { + console.warn('THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.'); + return new ExtrudeGeometry(this, options); + }, + makeGeometry: function makeGeometry(options) { + console.warn('THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.'); + return new ShapeGeometry(this, options); + } + }); + Object.assign(Vector2.prototype, { + fromAttribute: function fromAttribute(attribute, index, offset) { + console.warn('THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().'); + return this.fromBufferAttribute(attribute, index, offset); + }, + distanceToManhattan: function distanceToManhattan(v) { + console.warn('THREE.Vector2: .distanceToManhattan() has been renamed to .manhattanDistanceTo().'); + return this.manhattanDistanceTo(v); + }, + lengthManhattan: function lengthManhattan() { + console.warn('THREE.Vector2: .lengthManhattan() has been renamed to .manhattanLength().'); + return this.manhattanLength(); + } + }); + Object.assign(Vector3.prototype, { + setEulerFromRotationMatrix: function setEulerFromRotationMatrix() { + console.error('THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.'); + }, + setEulerFromQuaternion: function setEulerFromQuaternion() { + console.error('THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.'); + }, + getPositionFromMatrix: function getPositionFromMatrix(m) { + console.warn('THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().'); + return this.setFromMatrixPosition(m); + }, + getScaleFromMatrix: function getScaleFromMatrix(m) { + console.warn('THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().'); + return this.setFromMatrixScale(m); + }, + getColumnFromMatrix: function getColumnFromMatrix(index, matrix) { + console.warn('THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().'); + return this.setFromMatrixColumn(matrix, index); + }, + applyProjection: function applyProjection(m) { + console.warn('THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.'); + return this.applyMatrix4(m); + }, + fromAttribute: function fromAttribute(attribute, index, offset) { + console.warn('THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().'); + return this.fromBufferAttribute(attribute, index, offset); + }, + distanceToManhattan: function distanceToManhattan(v) { + console.warn('THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo().'); + return this.manhattanDistanceTo(v); + }, + lengthManhattan: function lengthManhattan() { + console.warn('THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength().'); + return this.manhattanLength(); + } + }); + Object.assign(Vector4.prototype, { + fromAttribute: function fromAttribute(attribute, index, offset) { + console.warn('THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().'); + return this.fromBufferAttribute(attribute, index, offset); + }, + lengthManhattan: function lengthManhattan() { + console.warn('THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength().'); + return this.manhattanLength(); + } + }); // - } else if ( light instanceof THREE.PointLight ) { + Object.assign(Geometry.prototype, { + computeTangents: function computeTangents() { + console.error('THREE.Geometry: .computeTangents() has been removed.'); + }, + computeLineDistances: function computeLineDistances() { + console.error('THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.'); + }, + applyMatrix: function applyMatrix(matrix) { + console.warn('THREE.Geometry: .applyMatrix() has been renamed to .applyMatrix4().'); + return this.applyMatrix4(matrix); + } + }); + Object.assign(Object3D.prototype, { + getChildByName: function getChildByName(name) { + console.warn('THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().'); + return this.getObjectByName(name); + }, + renderDepth: function renderDepth() { + console.warn('THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.'); + }, + translate: function translate(distance, axis) { + console.warn('THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.'); + return this.translateOnAxis(axis, distance); + }, + getWorldRotation: function getWorldRotation() { + console.error('THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.'); + }, + applyMatrix: function applyMatrix(matrix) { + console.warn('THREE.Object3D: .applyMatrix() has been renamed to .applyMatrix4().'); + return this.applyMatrix4(matrix); + } + }); + Object.defineProperties(Object3D.prototype, { + eulerOrder: { + get: function get() { + console.warn('THREE.Object3D: .eulerOrder is now .rotation.order.'); + return this.rotation.order; + }, + set: function set(value) { + console.warn('THREE.Object3D: .eulerOrder is now .rotation.order.'); + this.rotation.order = value; + } + }, + useQuaternion: { + get: function get() { + console.warn('THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.'); + }, + set: function set() { + console.warn('THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.'); + } + } + }); + Object.assign(Mesh.prototype, { + setDrawMode: function setDrawMode() { + console.error('THREE.Mesh: .setDrawMode() has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.'); + } + }); + Object.defineProperties(Mesh.prototype, { + drawMode: { + get: function get() { + console.error('THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode.'); + return TrianglesDrawMode; + }, + set: function set() { + console.error('THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.'); + } + } + }); + Object.defineProperties(LOD.prototype, { + objects: { + get: function get() { + console.warn('THREE.LOD: .objects has been renamed to .levels.'); + return this.levels; + } + } + }); + Object.defineProperty(Skeleton.prototype, 'useVertexTexture', { + get: function get() { + console.warn('THREE.Skeleton: useVertexTexture has been removed.'); + }, + set: function set() { + console.warn('THREE.Skeleton: useVertexTexture has been removed.'); + } + }); - var lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld ); + SkinnedMesh.prototype.initBones = function () { + console.error('THREE.SkinnedMesh: initBones() has been removed.'); + }; - var amount = normal.dot( _vector3.subVectors( lightPosition, position ).normalize() ); + Object.defineProperty(Curve.prototype, '__arcLengthDivisions', { + get: function get() { + console.warn('THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.'); + return this.arcLengthDivisions; + }, + set: function set(value) { + console.warn('THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.'); + this.arcLengthDivisions = value; + } + }); // - if ( amount <= 0 ) continue; + PerspectiveCamera.prototype.setLens = function (focalLength, filmGauge) { + console.warn("THREE.PerspectiveCamera.setLens is deprecated. " + "Use .setFocalLength and .filmGauge for a photographic setup."); + if (filmGauge !== undefined) this.filmGauge = filmGauge; + this.setFocalLength(focalLength); + }; // - amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 ); - if ( amount == 0 ) continue; + Object.defineProperties(Light.prototype, { + onlyShadow: { + set: function set() { + console.warn('THREE.Light: .onlyShadow has been removed.'); + } + }, + shadowCameraFov: { + set: function set(value) { + console.warn('THREE.Light: .shadowCameraFov is now .shadow.camera.fov.'); + this.shadow.camera.fov = value; + } + }, + shadowCameraLeft: { + set: function set(value) { + console.warn('THREE.Light: .shadowCameraLeft is now .shadow.camera.left.'); + this.shadow.camera.left = value; + } + }, + shadowCameraRight: { + set: function set(value) { + console.warn('THREE.Light: .shadowCameraRight is now .shadow.camera.right.'); + this.shadow.camera.right = value; + } + }, + shadowCameraTop: { + set: function set(value) { + console.warn('THREE.Light: .shadowCameraTop is now .shadow.camera.top.'); + this.shadow.camera.top = value; + } + }, + shadowCameraBottom: { + set: function set(value) { + console.warn('THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.'); + this.shadow.camera.bottom = value; + } + }, + shadowCameraNear: { + set: function set(value) { + console.warn('THREE.Light: .shadowCameraNear is now .shadow.camera.near.'); + this.shadow.camera.near = value; + } + }, + shadowCameraFar: { + set: function set(value) { + console.warn('THREE.Light: .shadowCameraFar is now .shadow.camera.far.'); + this.shadow.camera.far = value; + } + }, + shadowCameraVisible: { + set: function set() { + console.warn('THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.'); + } + }, + shadowBias: { + set: function set(value) { + console.warn('THREE.Light: .shadowBias is now .shadow.bias.'); + this.shadow.bias = value; + } + }, + shadowDarkness: { + set: function set() { + console.warn('THREE.Light: .shadowDarkness has been removed.'); + } + }, + shadowMapWidth: { + set: function set(value) { + console.warn('THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.'); + this.shadow.mapSize.width = value; + } + }, + shadowMapHeight: { + set: function set(value) { + console.warn('THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.'); + this.shadow.mapSize.height = value; + } + } + }); // - amount *= light.intensity; + Object.defineProperties(BufferAttribute.prototype, { + length: { + get: function get() { + console.warn('THREE.BufferAttribute: .length has been deprecated. Use .count instead.'); + return this.array.length; + } + }, + dynamic: { + get: function get() { + console.warn('THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.'); + return this.usage === DynamicDrawUsage; + }, + set: function set() + /* value */ + { + console.warn('THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.'); + this.setUsage(DynamicDrawUsage); + } + } + }); + Object.assign(BufferAttribute.prototype, { + setDynamic: function setDynamic(value) { + console.warn('THREE.BufferAttribute: .setDynamic() has been deprecated. Use .setUsage() instead.'); + this.setUsage(value === true ? DynamicDrawUsage : StaticDrawUsage); + return this; + }, + copyIndicesArray: function copyIndicesArray() + /* indices */ + { + console.error('THREE.BufferAttribute: .copyIndicesArray() has been removed.'); + }, + setArray: function setArray() + /* array */ + { + console.error('THREE.BufferAttribute: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers'); + } + }); + Object.assign(BufferGeometry.prototype, { + addIndex: function addIndex(index) { + console.warn('THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().'); + this.setIndex(index); + }, + addAttribute: function addAttribute(name, attribute) { + console.warn('THREE.BufferGeometry: .addAttribute() has been renamed to .setAttribute().'); - color.add( _lightColor.multiplyScalar( amount ) ); + if (!(attribute && attribute.isBufferAttribute) && !(attribute && attribute.isInterleavedBufferAttribute)) { + console.warn('THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).'); + return this.setAttribute(name, new BufferAttribute(arguments[1], arguments[2])); + } + if (name === 'index') { + console.warn('THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.'); + this.setIndex(attribute); + return this; } - } - - } - - function renderSprite( v1, element, material ) { - - setOpacity( material.opacity ); - setBlending( material.blending ); - - var scaleX = element.scale.x * _canvasWidthHalf; - var scaleY = element.scale.y * _canvasHeightHalf; - - var dist = 0.5 * Math.sqrt( scaleX * scaleX + scaleY * scaleY ); // allow for rotated sprite - _elemBox.min.set( v1.x - dist, v1.y - dist ); - _elemBox.max.set( v1.x + dist, v1.y + dist ); - - if ( material instanceof THREE.SpriteMaterial || - material instanceof THREE.ParticleSystemMaterial ) { // Backwards compatibility - - var texture = material.map; - - if ( texture !== null ) { - - if ( texture.hasEventListener( 'update', onTextureUpdate ) === false ) { - - if ( texture.image !== undefined && texture.image.width > 0 ) { - - textureToPattern( texture ); - - } - - texture.addEventListener( 'update', onTextureUpdate ); - - } - - var pattern = _patterns[ texture.id ]; - - if ( pattern !== undefined ) { - - setFillStyle( pattern ); - - } else { - - setFillStyle( 'rgba( 0, 0, 0, 1 )' ); - - } - - // - - var bitmap = texture.image; - - var ox = bitmap.width * texture.offset.x; - var oy = bitmap.height * texture.offset.y; - - var sx = bitmap.width * texture.repeat.x; - var sy = bitmap.height * texture.repeat.y; - - var cx = scaleX / sx; - var cy = scaleY / sy; - - _context.save(); - _context.translate( v1.x, v1.y ); - if ( material.rotation !== 0 ) _context.rotate( material.rotation ); - _context.translate( - scaleX / 2, - scaleY / 2 ); - _context.scale( cx, cy ); - _context.translate( - ox, - oy ); - _context.fillRect( ox, oy, sx, sy ); - _context.restore(); - - } else { // no texture - - setFillStyle( material.color.getStyle() ); - - _context.save(); - _context.translate( v1.x, v1.y ); - if ( material.rotation !== 0 ) _context.rotate( material.rotation ); - _context.scale( scaleX, - scaleY ); - _context.fillRect( - 0.5, - 0.5, 1, 1 ); - _context.restore(); - - } - - } else if ( material instanceof THREE.SpriteCanvasMaterial ) { - - setStrokeStyle( material.color.getStyle() ); - setFillStyle( material.color.getStyle() ); - - _context.save(); - _context.translate( v1.x, v1.y ); - if ( material.rotation !== 0 ) _context.rotate( material.rotation ); - _context.scale( scaleX, scaleY ); - - material.program( _context ); - - _context.restore(); - - } - - /* DEBUG - setStrokeStyle( 'rgb(255,255,0)' ); - _context.beginPath(); - _context.moveTo( v1.x - 10, v1.y ); - _context.lineTo( v1.x + 10, v1.y ); - _context.moveTo( v1.x, v1.y - 10 ); - _context.lineTo( v1.x, v1.y + 10 ); - _context.stroke(); - */ - - } - - function renderLine( v1, v2, element, material ) { - - setOpacity( material.opacity ); - setBlending( material.blending ); - - _context.beginPath(); - _context.moveTo( v1.positionScreen.x, v1.positionScreen.y ); - _context.lineTo( v2.positionScreen.x, v2.positionScreen.y ); - - if ( material instanceof THREE.LineBasicMaterial ) { - - setLineWidth( material.linewidth ); - setLineCap( material.linecap ); - setLineJoin( material.linejoin ); - - if ( material.vertexColors !== THREE.VertexColors ) { - - setStrokeStyle( material.color.getStyle() ); - - } else { - - var colorStyle1 = element.vertexColors[0].getStyle(); - var colorStyle2 = element.vertexColors[1].getStyle(); - - if ( colorStyle1 === colorStyle2 ) { - - setStrokeStyle( colorStyle1 ); - - } else { - - try { - - var grad = _context.createLinearGradient( - v1.positionScreen.x, - v1.positionScreen.y, - v2.positionScreen.x, - v2.positionScreen.y - ); - grad.addColorStop( 0, colorStyle1 ); - grad.addColorStop( 1, colorStyle2 ); - - } catch ( exception ) { - - grad = colorStyle1; - - } - - setStrokeStyle( grad ); - - } - - } - - _context.stroke(); - _elemBox.expandByScalar( material.linewidth * 2 ); - - } else if ( material instanceof THREE.LineDashedMaterial ) { - - setLineWidth( material.linewidth ); - setLineCap( material.linecap ); - setLineJoin( material.linejoin ); - setStrokeStyle( material.color.getStyle() ); - setDashAndGap( material.dashSize, material.gapSize ); - - _context.stroke(); - - _elemBox.expandByScalar( material.linewidth * 2 ); - - setDashAndGap( null, null ); - - } - - } - - function renderFace3( v1, v2, v3, uv1, uv2, uv3, element, material ) { - - _this.info.render.vertices += 3; - _this.info.render.faces ++; - - setOpacity( material.opacity ); - setBlending( material.blending ); - - _v1x = v1.positionScreen.x; _v1y = v1.positionScreen.y; - _v2x = v2.positionScreen.x; _v2y = v2.positionScreen.y; - _v3x = v3.positionScreen.x; _v3y = v3.positionScreen.y; - - drawTriangle( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y ); - - if ( ( material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) && material.map === null ) { - - _diffuseColor.copy( material.color ); - _emissiveColor.copy( material.emissive ); - - if ( material.vertexColors === THREE.FaceColors ) { - - _diffuseColor.multiply( element.color ); - - } - - _color.copy( _ambientLight ); - - _centroid.copy( v1.positionWorld ).add( v2.positionWorld ).add( v3.positionWorld ).divideScalar( 3 ); - - calculateLight( _centroid, element.normalModel, _color ); - - _color.multiply( _diffuseColor ).add( _emissiveColor ); - - material.wireframe === true - ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) - : fillPath( _color ); - - } else if ( material instanceof THREE.MeshBasicMaterial || material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) { - - if ( material.map !== null ) { - - if ( material.map.mapping instanceof THREE.UVMapping ) { - - _uvs = element.uvs; - patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uvs[ uv1 ].x, _uvs[ uv1 ].y, _uvs[ uv2 ].x, _uvs[ uv2 ].y, _uvs[ uv3 ].x, _uvs[ uv3 ].y, material.map ); - - } - - } else if ( material.envMap !== null ) { - - if ( material.envMap.mapping instanceof THREE.SphericalReflectionMapping ) { - - _normal.copy( element.vertexNormalsModel[ uv1 ] ).applyMatrix3( _normalViewMatrix ); - _uv1x = 0.5 * _normal.x + 0.5; - _uv1y = 0.5 * _normal.y + 0.5; - - _normal.copy( element.vertexNormalsModel[ uv2 ] ).applyMatrix3( _normalViewMatrix ); - _uv2x = 0.5 * _normal.x + 0.5; - _uv2y = 0.5 * _normal.y + 0.5; - - _normal.copy( element.vertexNormalsModel[ uv3 ] ).applyMatrix3( _normalViewMatrix ); - _uv3x = 0.5 * _normal.x + 0.5; - _uv3y = 0.5 * _normal.y + 0.5; - - patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y, material.envMap ); - - } else if ( material.envMap.mapping instanceof THREE.SphericalRefractionMapping ) { - - _normal.copy( element.vertexNormalsModel[ uv1 ] ).applyMatrix3( _normalViewMatrix ); - _uv1x = - 0.5 * _normal.x + 0.5; - _uv1y = - 0.5 * _normal.y + 0.5; - - _normal.copy( element.vertexNormalsModel[ uv2 ] ).applyMatrix3( _normalViewMatrix ); - _uv2x = - 0.5 * _normal.x + 0.5; - _uv2y = - 0.5 * _normal.y + 0.5; - - _normal.copy( element.vertexNormalsModel[ uv3 ] ).applyMatrix3( _normalViewMatrix ); - _uv3x = - 0.5 * _normal.x + 0.5; - _uv3y = - 0.5 * _normal.y + 0.5; - - patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y, material.envMap ); - - } - - - } else { - - _color.copy( material.color ); - - if ( material.vertexColors === THREE.FaceColors ) { - - _color.multiply( element.color ); - - } - - material.wireframe === true - ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) - : fillPath( _color ); - - } - - } else if ( material instanceof THREE.MeshDepthMaterial ) { - - _color.r = _color.g = _color.b = 1 - smoothstep( v1.positionScreen.z * v1.positionScreen.w, _camera.near, _camera.far ); - - material.wireframe === true - ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) - : fillPath( _color ); - - } else if ( material instanceof THREE.MeshNormalMaterial ) { - - _normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix ); - - _color.setRGB( _normal.x, _normal.y, _normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 ); - - material.wireframe === true - ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) - : fillPath( _color ); - - } else { - - _color.setRGB( 1, 1, 1 ); - - material.wireframe === true - ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) - : fillPath( _color ); - - } - - } - - // - - function drawTriangle( x0, y0, x1, y1, x2, y2 ) { - - _context.beginPath(); - _context.moveTo( x0, y0 ); - _context.lineTo( x1, y1 ); - _context.lineTo( x2, y2 ); - _context.closePath(); - - } - - function strokePath( color, linewidth, linecap, linejoin ) { - - setLineWidth( linewidth ); - setLineCap( linecap ); - setLineJoin( linejoin ); - setStrokeStyle( color.getStyle() ); - - _context.stroke(); - - _elemBox.expandByScalar( linewidth * 2 ); - - } - - function fillPath( color ) { - - setFillStyle( color.getStyle() ); - _context.fill(); - - } - - function onTextureUpdate ( event ) { - - textureToPattern( event.target ); - - } - - function textureToPattern( texture ) { - - var repeatX = texture.wrapS === THREE.RepeatWrapping; - var repeatY = texture.wrapT === THREE.RepeatWrapping; - - var image = texture.image; - - var canvas = document.createElement( 'canvas' ); - canvas.width = image.width; - canvas.height = image.height; - - var context = canvas.getContext( '2d' ); - context.setTransform( 1, 0, 0, - 1, 0, image.height ); - context.drawImage( image, 0, 0 ); - - _patterns[ texture.id ] = _context.createPattern( - canvas, repeatX === true && repeatY === true - ? 'repeat' - : repeatX === true && repeatY === false - ? 'repeat-x' - : repeatX === false && repeatY === true - ? 'repeat-y' - : 'no-repeat' - ); - - } - - function patternPath( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, texture ) { - - if ( texture instanceof THREE.DataTexture ) return; - - if ( texture.hasEventListener( 'update', onTextureUpdate ) === false ) { - - if ( texture.image !== undefined && texture.image.width > 0 ) { - - textureToPattern( texture ); - - } - - texture.addEventListener( 'update', onTextureUpdate ); - - } - - var pattern = _patterns[ texture.id ]; - - if ( pattern !== undefined ) { - - setFillStyle( pattern ); - - } else { - - setFillStyle( 'rgba(0,0,0,1)' ); - _context.fill(); - - return; - - } - - // http://extremelysatisfactorytotalitarianism.com/blog/?p=2120 - - var a, b, c, d, e, f, det, idet, - offsetX = texture.offset.x / texture.repeat.x, - offsetY = texture.offset.y / texture.repeat.y, - width = texture.image.width * texture.repeat.x, - height = texture.image.height * texture.repeat.y; - - u0 = ( u0 + offsetX ) * width; - v0 = ( v0 + offsetY ) * height; - - u1 = ( u1 + offsetX ) * width; - v1 = ( v1 + offsetY ) * height; - - u2 = ( u2 + offsetX ) * width; - v2 = ( v2 + offsetY ) * height; - - x1 -= x0; y1 -= y0; - x2 -= x0; y2 -= y0; - - u1 -= u0; v1 -= v0; - u2 -= u0; v2 -= v0; - - det = u1 * v2 - u2 * v1; - - if ( det === 0 ) return; - - idet = 1 / det; - - a = ( v2 * x1 - v1 * x2 ) * idet; - b = ( v2 * y1 - v1 * y2 ) * idet; - c = ( u1 * x2 - u2 * x1 ) * idet; - d = ( u1 * y2 - u2 * y1 ) * idet; - - e = x0 - a * u0 - c * v0; - f = y0 - b * u0 - d * v0; - - _context.save(); - _context.transform( a, b, c, d, e, f ); - _context.fill(); - _context.restore(); - - } - - function clipImage( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, image ) { - - // http://extremelysatisfactorytotalitarianism.com/blog/?p=2120 - - var a, b, c, d, e, f, det, idet, - width = image.width - 1, - height = image.height - 1; - - u0 *= width; v0 *= height; - u1 *= width; v1 *= height; - u2 *= width; v2 *= height; - - x1 -= x0; y1 -= y0; - x2 -= x0; y2 -= y0; - - u1 -= u0; v1 -= v0; - u2 -= u0; v2 -= v0; - - det = u1 * v2 - u2 * v1; - - idet = 1 / det; - - a = ( v2 * x1 - v1 * x2 ) * idet; - b = ( v2 * y1 - v1 * y2 ) * idet; - c = ( u1 * x2 - u2 * x1 ) * idet; - d = ( u1 * y2 - u2 * y1 ) * idet; - - e = x0 - a * u0 - c * v0; - f = y0 - b * u0 - d * v0; - - _context.save(); - _context.transform( a, b, c, d, e, f ); - _context.clip(); - _context.drawImage( image, 0, 0 ); - _context.restore(); - - } - - // Hide anti-alias gaps - - function expand( v1, v2, pixels ) { - - var x = v2.x - v1.x, y = v2.y - v1.y, - det = x * x + y * y, idet; - - if ( det === 0 ) return; - - idet = pixels / Math.sqrt( det ); - - x *= idet; y *= idet; - - v2.x += x; v2.y += y; - v1.x -= x; v1.y -= y; - - } - - // Context cached methods. - - function setOpacity( value ) { - - if ( _contextGlobalAlpha !== value ) { - - _context.globalAlpha = value; - _contextGlobalAlpha = value; - - } - - } - - function setBlending( value ) { - - if ( _contextGlobalCompositeOperation !== value ) { - - if ( value === THREE.NormalBlending ) { - - _context.globalCompositeOperation = 'source-over'; - - } else if ( value === THREE.AdditiveBlending ) { - - _context.globalCompositeOperation = 'lighter'; - - } else if ( value === THREE.SubtractiveBlending ) { - - _context.globalCompositeOperation = 'darker'; - - } - - _contextGlobalCompositeOperation = value; - - } - - } - - function setLineWidth( value ) { - - if ( _contextLineWidth !== value ) { - - _context.lineWidth = value; - _contextLineWidth = value; - - } - - } - - function setLineCap( value ) { - - // "butt", "round", "square" - - if ( _contextLineCap !== value ) { - - _context.lineCap = value; - _contextLineCap = value; - - } - - } - - function setLineJoin( value ) { - - // "round", "bevel", "miter" - - if ( _contextLineJoin !== value ) { - - _context.lineJoin = value; - _contextLineJoin = value; - - } - - } - - function setStrokeStyle( value ) { - - if ( _contextStrokeStyle !== value ) { - - _context.strokeStyle = value; - _contextStrokeStyle = value; - - } - - } - - function setFillStyle( value ) { - - if ( _contextFillStyle !== value ) { - - _context.fillStyle = value; - _contextFillStyle = value; - - } - - } - - function setDashAndGap( dashSizeValue, gapSizeValue ) { - - if ( _contextDashSize !== dashSizeValue || _contextGapSize !== gapSizeValue ) { - - _context.setLineDash( [ dashSizeValue, gapSizeValue ] ); - _contextDashSize = dashSizeValue; - _contextGapSize = gapSizeValue; - - } - - } - -}; - -/** - * Shader chunks for WebLG Shader library - * - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - */ - -THREE.ShaderChunk = { - - // FOG - - fog_pars_fragment: [ - - "#ifdef USE_FOG", - - " uniform vec3 fogColor;", - - " #ifdef FOG_EXP2", - - " uniform float fogDensity;", - - " #else", - - " uniform float fogNear;", - " uniform float fogFar;", - - " #endif", - - "#endif" - - ].join("\n"), - - fog_fragment: [ - - "#ifdef USE_FOG", - - " #ifdef USE_LOGDEPTHBUF_EXT", - - " float depth = gl_FragDepthEXT / gl_FragCoord.w;", - - " #else", - - " float depth = gl_FragCoord.z / gl_FragCoord.w;", - - " #endif", - - " #ifdef FOG_EXP2", - - " const float LOG2 = 1.442695;", - " float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );", - " fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );", - - " #else", - - " float fogFactor = smoothstep( fogNear, fogFar, depth );", - - " #endif", - - " gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );", - - "#endif" - - ].join("\n"), - - // ENVIRONMENT MAP - - envmap_pars_fragment: [ - - "#ifdef USE_ENVMAP", - - " uniform float reflectivity;", - " uniform samplerCube envMap;", - " uniform float flipEnvMap;", - " uniform int combine;", - - " #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )", - - " uniform bool useRefract;", - " uniform float refractionRatio;", - - " #else", - - " varying vec3 vReflect;", - - " #endif", - - "#endif" - - ].join("\n"), - - envmap_fragment: [ - - "#ifdef USE_ENVMAP", - - " vec3 reflectVec;", - - " #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )", - - " vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );", - - // http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations - // "Transforming Normal Vectors with the Inverse Transformation" - - " vec3 worldNormal = normalize( vec3( vec4( normal, 0.0 ) * viewMatrix ) );", - - " if ( useRefract ) {", - - " reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );", - - " } else { ", - - " reflectVec = reflect( cameraToVertex, worldNormal );", - - " }", - - " #else", - - " reflectVec = vReflect;", - - " #endif", - - " #ifdef DOUBLE_SIDED", - - " float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );", - " vec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );", - - " #else", - - " vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );", - - " #endif", - - " #ifdef GAMMA_INPUT", - - " cubeColor.xyz *= cubeColor.xyz;", - - " #endif", - - " if ( combine == 1 ) {", - - " gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularStrength * reflectivity );", - - " } else if ( combine == 2 ) {", - - " gl_FragColor.xyz += cubeColor.xyz * specularStrength * reflectivity;", - - " } else {", - - " gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * cubeColor.xyz, specularStrength * reflectivity );", - - " }", - - "#endif" - - ].join("\n"), - - envmap_pars_vertex: [ - - "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP )", - - " varying vec3 vReflect;", - - " uniform float refractionRatio;", - " uniform bool useRefract;", - - "#endif" - - ].join("\n"), - - worldpos_vertex : [ - - "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )", - - " #ifdef USE_SKINNING", - - " vec4 worldPosition = modelMatrix * skinned;", - - " #endif", - - " #if defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )", - - " vec4 worldPosition = modelMatrix * vec4( morphed, 1.0 );", - - " #endif", - - " #if ! defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )", - - " vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", - - " #endif", - - "#endif" - - ].join("\n"), - - envmap_vertex : [ - - "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP )", - - " vec3 worldNormal = mat3( modelMatrix[ 0 ].xyz, modelMatrix[ 1 ].xyz, modelMatrix[ 2 ].xyz ) * objectNormal;", - " worldNormal = normalize( worldNormal );", - - " vec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );", - - " if ( useRefract ) {", - - " vReflect = refract( cameraToVertex, worldNormal, refractionRatio );", - - " } else {", - - " vReflect = reflect( cameraToVertex, worldNormal );", - - " }", - - "#endif" - - ].join("\n"), - - // COLOR MAP (particles) - - map_particle_pars_fragment: [ - - "#ifdef USE_MAP", - - " uniform sampler2D map;", - - "#endif" - - ].join("\n"), - - - map_particle_fragment: [ - - "#ifdef USE_MAP", - - " gl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );", - - "#endif" - - ].join("\n"), - - // COLOR MAP (triangles) - - map_pars_vertex: [ - - "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )", - - " varying vec2 vUv;", - " uniform vec4 offsetRepeat;", - - "#endif" - - ].join("\n"), - - map_pars_fragment: [ - - "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )", - - " varying vec2 vUv;", - - "#endif", - - "#ifdef USE_MAP", - - " uniform sampler2D map;", - - "#endif" - - ].join("\n"), - - map_vertex: [ - - "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )", - - " vUv = uv * offsetRepeat.zw + offsetRepeat.xy;", - - "#endif" - - ].join("\n"), - - map_fragment: [ - - "#ifdef USE_MAP", - - " vec4 texelColor = texture2D( map, vUv );", - - " #ifdef GAMMA_INPUT", - - " texelColor.xyz *= texelColor.xyz;", - - " #endif", - - " gl_FragColor = gl_FragColor * texelColor;", - - "#endif" - - ].join("\n"), - - // LIGHT MAP - - lightmap_pars_fragment: [ - - "#ifdef USE_LIGHTMAP", - - " varying vec2 vUv2;", - " uniform sampler2D lightMap;", - - "#endif" - - ].join("\n"), - - lightmap_pars_vertex: [ - - "#ifdef USE_LIGHTMAP", - - " varying vec2 vUv2;", - - "#endif" - - ].join("\n"), - - lightmap_fragment: [ - - "#ifdef USE_LIGHTMAP", - - " gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );", - - "#endif" - - ].join("\n"), - - lightmap_vertex: [ - - "#ifdef USE_LIGHTMAP", - - " vUv2 = uv2;", - - "#endif" - - ].join("\n"), - - // BUMP MAP - - bumpmap_pars_fragment: [ - - "#ifdef USE_BUMPMAP", - - " uniform sampler2D bumpMap;", - " uniform float bumpScale;", - - // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen - // http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html - - // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2) - - " vec2 dHdxy_fwd() {", - - " vec2 dSTdx = dFdx( vUv );", - " vec2 dSTdy = dFdy( vUv );", - - " float Hll = bumpScale * texture2D( bumpMap, vUv ).x;", - " float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;", - " float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;", - - " return vec2( dBx, dBy );", - - " }", - - " vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {", - - " vec3 vSigmaX = dFdx( surf_pos );", - " vec3 vSigmaY = dFdy( surf_pos );", - " vec3 vN = surf_norm;", // normalized - - " vec3 R1 = cross( vSigmaY, vN );", - " vec3 R2 = cross( vN, vSigmaX );", - - " float fDet = dot( vSigmaX, R1 );", - - " vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );", - " return normalize( abs( fDet ) * surf_norm - vGrad );", - - " }", - - "#endif" - - ].join("\n"), - - // NORMAL MAP - - normalmap_pars_fragment: [ - - "#ifdef USE_NORMALMAP", - - " uniform sampler2D normalMap;", - " uniform vec2 normalScale;", - - // Per-Pixel Tangent Space Normal Mapping - // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html - - " vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {", - - " vec3 q0 = dFdx( eye_pos.xyz );", - " vec3 q1 = dFdy( eye_pos.xyz );", - " vec2 st0 = dFdx( vUv.st );", - " vec2 st1 = dFdy( vUv.st );", - - " vec3 S = normalize( q0 * st1.t - q1 * st0.t );", - " vec3 T = normalize( -q0 * st1.s + q1 * st0.s );", - " vec3 N = normalize( surf_norm );", - - " vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;", - " mapN.xy = normalScale * mapN.xy;", - " mat3 tsn = mat3( S, T, N );", - " return normalize( tsn * mapN );", - - " }", - - "#endif" - - ].join("\n"), - - // SPECULAR MAP - - specularmap_pars_fragment: [ - - "#ifdef USE_SPECULARMAP", - - " uniform sampler2D specularMap;", - - "#endif" - - ].join("\n"), - - specularmap_fragment: [ - - "float specularStrength;", - - "#ifdef USE_SPECULARMAP", - - " vec4 texelSpecular = texture2D( specularMap, vUv );", - " specularStrength = texelSpecular.r;", - - "#else", - - " specularStrength = 1.0;", - - "#endif" - - ].join("\n"), - - // LIGHTS LAMBERT - - lights_lambert_pars_vertex: [ - - "uniform vec3 ambient;", - "uniform vec3 diffuse;", - "uniform vec3 emissive;", - - "uniform vec3 ambientLightColor;", - - "#if MAX_DIR_LIGHTS > 0", - - " uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];", - " uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];", - - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - - " uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];", - " uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];", - " uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];", - - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - - " uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", - " uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", - " uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - - "#endif", - - "#if MAX_SPOT_LIGHTS > 0", - - " uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];", - " uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];", - " uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];", - " uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];", - " uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];", - " uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];", - - "#endif", - - "#ifdef WRAP_AROUND", - - " uniform vec3 wrapRGB;", - - "#endif" - - ].join("\n"), - - lights_lambert_vertex: [ - - "vLightFront = vec3( 0.0 );", - - "#ifdef DOUBLE_SIDED", - - " vLightBack = vec3( 0.0 );", - - "#endif", - - "transformedNormal = normalize( transformedNormal );", - - "#if MAX_DIR_LIGHTS > 0", - - "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {", - - " vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );", - " vec3 dirVector = normalize( lDirection.xyz );", - - " float dotProduct = dot( transformedNormal, dirVector );", - " vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );", - - " #ifdef DOUBLE_SIDED", - - " vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );", - - " #ifdef WRAP_AROUND", - - " vec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );", - - " #endif", - - " #endif", - - " #ifdef WRAP_AROUND", - - " vec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );", - " directionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );", - - " #ifdef DOUBLE_SIDED", - - " directionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );", - - " #endif", - - " #endif", - - " vLightFront += directionalLightColor[ i ] * directionalLightWeighting;", - - " #ifdef DOUBLE_SIDED", - - " vLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;", - - " #endif", - - "}", - - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - - " for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", - - " vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", - " vec3 lVector = lPosition.xyz - mvPosition.xyz;", - - " float lDistance = 1.0;", - " if ( pointLightDistance[ i ] > 0.0 )", - " lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );", - - " lVector = normalize( lVector );", - " float dotProduct = dot( transformedNormal, lVector );", - - " vec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );", - - " #ifdef DOUBLE_SIDED", - - " vec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );", - - " #ifdef WRAP_AROUND", - - " vec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );", - - " #endif", - - " #endif", - - " #ifdef WRAP_AROUND", - - " vec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );", - " pointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );", - - " #ifdef DOUBLE_SIDED", - - " pointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );", - - " #endif", - - " #endif", - - " vLightFront += pointLightColor[ i ] * pointLightWeighting * lDistance;", - - " #ifdef DOUBLE_SIDED", - - " vLightBack += pointLightColor[ i ] * pointLightWeightingBack * lDistance;", - - " #endif", - - " }", - - "#endif", - - "#if MAX_SPOT_LIGHTS > 0", - - " for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {", - - " vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );", - " vec3 lVector = lPosition.xyz - mvPosition.xyz;", - - " float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );", - - " if ( spotEffect > spotLightAngleCos[ i ] ) {", - - " spotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );", - - " float lDistance = 1.0;", - " if ( spotLightDistance[ i ] > 0.0 )", - " lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );", - - " lVector = normalize( lVector );", - - " float dotProduct = dot( transformedNormal, lVector );", - " vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );", - - " #ifdef DOUBLE_SIDED", - - " vec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );", - - " #ifdef WRAP_AROUND", - - " vec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );", - - " #endif", - - " #endif", - - " #ifdef WRAP_AROUND", - - " vec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );", - " spotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );", - - " #ifdef DOUBLE_SIDED", - - " spotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );", - - " #endif", - - " #endif", - - " vLightFront += spotLightColor[ i ] * spotLightWeighting * lDistance * spotEffect;", - - " #ifdef DOUBLE_SIDED", - - " vLightBack += spotLightColor[ i ] * spotLightWeightingBack * lDistance * spotEffect;", - - " #endif", - - " }", - - " }", - - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - - " for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {", - - " vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );", - " vec3 lVector = normalize( lDirection.xyz );", - - " float dotProduct = dot( transformedNormal, lVector );", - - " float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;", - " float hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;", - - " vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", - - " #ifdef DOUBLE_SIDED", - - " vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );", - - " #endif", - - " }", - - "#endif", - - "vLightFront = vLightFront * diffuse + ambient * ambientLightColor + emissive;", - - "#ifdef DOUBLE_SIDED", - - " vLightBack = vLightBack * diffuse + ambient * ambientLightColor + emissive;", - - "#endif" - - ].join("\n"), - - // LIGHTS PHONG - - lights_phong_pars_vertex: [ - - "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )", - - " varying vec3 vWorldPosition;", - - "#endif" - - ].join("\n"), - - - lights_phong_vertex: [ - - "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )", - - " vWorldPosition = worldPosition.xyz;", - - "#endif" - - ].join("\n"), - - lights_phong_pars_fragment: [ - - "uniform vec3 ambientLightColor;", - - "#if MAX_DIR_LIGHTS > 0", - - " uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];", - " uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];", - - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - - " uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];", - " uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];", - " uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];", - - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - - " uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", - - " uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", - " uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - - "#endif", - - "#if MAX_SPOT_LIGHTS > 0", - - " uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];", - " uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];", - " uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];", - " uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];", - " uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];", - - " uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];", - - "#endif", - - "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP )", - - " varying vec3 vWorldPosition;", - - "#endif", - - "#ifdef WRAP_AROUND", - - " uniform vec3 wrapRGB;", - - "#endif", - - "varying vec3 vViewPosition;", - "varying vec3 vNormal;" - - ].join("\n"), - - lights_phong_fragment: [ - - "vec3 normal = normalize( vNormal );", - "vec3 viewPosition = normalize( vViewPosition );", - - "#ifdef DOUBLE_SIDED", - - " normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );", - - "#endif", - - "#ifdef USE_NORMALMAP", - - " normal = perturbNormal2Arb( -vViewPosition, normal );", - - "#elif defined( USE_BUMPMAP )", - - " normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );", - - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - - " vec3 pointDiffuse = vec3( 0.0 );", - " vec3 pointSpecular = vec3( 0.0 );", - - " for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", - - " vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", - " vec3 lVector = lPosition.xyz + vViewPosition.xyz;", - - " float lDistance = 1.0;", - " if ( pointLightDistance[ i ] > 0.0 )", - " lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );", - - " lVector = normalize( lVector );", - - // diffuse - - " float dotProduct = dot( normal, lVector );", - - " #ifdef WRAP_AROUND", - - " float pointDiffuseWeightFull = max( dotProduct, 0.0 );", - " float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );", - - " vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );", - - " #else", - - " float pointDiffuseWeight = max( dotProduct, 0.0 );", - - " #endif", - - " pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;", - - // specular - - " vec3 pointHalfVector = normalize( lVector + viewPosition );", - " float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );", - " float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );", - - // 2.0 => 2.0001 is hack to work around ANGLE bug - - " float specularNormalization = ( shininess + 2.0001 ) / 8.0;", - - " vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );", - " pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;", - - " }", - - "#endif", - - "#if MAX_SPOT_LIGHTS > 0", - - " vec3 spotDiffuse = vec3( 0.0 );", - " vec3 spotSpecular = vec3( 0.0 );", - - " for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {", - - " vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );", - " vec3 lVector = lPosition.xyz + vViewPosition.xyz;", - - " float lDistance = 1.0;", - " if ( spotLightDistance[ i ] > 0.0 )", - " lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );", - - " lVector = normalize( lVector );", - - " float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );", - - " if ( spotEffect > spotLightAngleCos[ i ] ) {", - - " spotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );", - - // diffuse - - " float dotProduct = dot( normal, lVector );", - - " #ifdef WRAP_AROUND", - - " float spotDiffuseWeightFull = max( dotProduct, 0.0 );", - " float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );", - - " vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );", - - " #else", - - " float spotDiffuseWeight = max( dotProduct, 0.0 );", - - " #endif", - - " spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;", - - // specular - - " vec3 spotHalfVector = normalize( lVector + viewPosition );", - " float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );", - " float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );", - - // 2.0 => 2.0001 is hack to work around ANGLE bug - - " float specularNormalization = ( shininess + 2.0001 ) / 8.0;", - - " vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );", - " spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;", - - " }", - - " }", - - "#endif", - - "#if MAX_DIR_LIGHTS > 0", - - " vec3 dirDiffuse = vec3( 0.0 );", - " vec3 dirSpecular = vec3( 0.0 );" , - - " for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {", - - " vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );", - " vec3 dirVector = normalize( lDirection.xyz );", - - // diffuse - - " float dotProduct = dot( normal, dirVector );", - - " #ifdef WRAP_AROUND", - - " float dirDiffuseWeightFull = max( dotProduct, 0.0 );", - " float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );", - - " vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );", - - " #else", - - " float dirDiffuseWeight = max( dotProduct, 0.0 );", - - " #endif", - - " dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;", - - // specular - - " vec3 dirHalfVector = normalize( dirVector + viewPosition );", - " float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );", - " float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );", - - /* - // fresnel term from skin shader - " const float F0 = 0.128;", - - " float base = 1.0 - dot( viewPosition, dirHalfVector );", - " float exponential = pow( base, 5.0 );", - - " float fresnel = exponential + F0 * ( 1.0 - exponential );", - */ - - /* - // fresnel term from fresnel shader - " const float mFresnelBias = 0.08;", - " const float mFresnelScale = 0.3;", - " const float mFresnelPower = 5.0;", - - " float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );", - */ - - // 2.0 => 2.0001 is hack to work around ANGLE bug - - " float specularNormalization = ( shininess + 2.0001 ) / 8.0;", - - //"dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;", - - " vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );", - " dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;", - - - " }", - - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - - " vec3 hemiDiffuse = vec3( 0.0 );", - " vec3 hemiSpecular = vec3( 0.0 );" , - - " for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {", - - " vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );", - " vec3 lVector = normalize( lDirection.xyz );", - - // diffuse - - " float dotProduct = dot( normal, lVector );", - " float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;", - - " vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", - - " hemiDiffuse += diffuse * hemiColor;", - - // specular (sky light) - - " vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );", - " float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;", - " float hemiSpecularWeightSky = specularStrength * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );", - - // specular (ground light) - - " vec3 lVectorGround = -lVector;", - - " vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );", - " float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;", - " float hemiSpecularWeightGround = specularStrength * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );", - - " float dotProductGround = dot( normal, lVectorGround );", - - // 2.0 => 2.0001 is hack to work around ANGLE bug - - " float specularNormalization = ( shininess + 2.0001 ) / 8.0;", - - " vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );", - " vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );", - " hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );", - - " }", - - "#endif", - - "vec3 totalDiffuse = vec3( 0.0 );", - "vec3 totalSpecular = vec3( 0.0 );", - - "#if MAX_DIR_LIGHTS > 0", - - " totalDiffuse += dirDiffuse;", - " totalSpecular += dirSpecular;", - - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - - " totalDiffuse += hemiDiffuse;", - " totalSpecular += hemiSpecular;", - - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - - " totalDiffuse += pointDiffuse;", - " totalSpecular += pointSpecular;", - - "#endif", - - "#if MAX_SPOT_LIGHTS > 0", - - " totalDiffuse += spotDiffuse;", - " totalSpecular += spotSpecular;", - - "#endif", - - "#ifdef METAL", - - " gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );", - - "#else", - - " gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;", - - "#endif" - - ].join("\n"), - - // VERTEX COLORS - - color_pars_fragment: [ - - "#ifdef USE_COLOR", - - " varying vec3 vColor;", - - "#endif" - - ].join("\n"), - - - color_fragment: [ - - "#ifdef USE_COLOR", - - " gl_FragColor = gl_FragColor * vec4( vColor, 1.0 );", - - "#endif" - - ].join("\n"), - - color_pars_vertex: [ - - "#ifdef USE_COLOR", - - " varying vec3 vColor;", - - "#endif" - - ].join("\n"), - - - color_vertex: [ - - "#ifdef USE_COLOR", - - " #ifdef GAMMA_INPUT", - - " vColor = color * color;", - - " #else", - - " vColor = color;", - - " #endif", - - "#endif" - - ].join("\n"), - - // SKINNING - - skinning_pars_vertex: [ - - "#ifdef USE_SKINNING", - - " #ifdef BONE_TEXTURE", - - " uniform sampler2D boneTexture;", - " uniform int boneTextureWidth;", - " uniform int boneTextureHeight;", - - " mat4 getBoneMatrix( const in float i ) {", - - " float j = i * 4.0;", - " float x = mod( j, float( boneTextureWidth ) );", - " float y = floor( j / float( boneTextureWidth ) );", - - " float dx = 1.0 / float( boneTextureWidth );", - " float dy = 1.0 / float( boneTextureHeight );", - - " y = dy * ( y + 0.5 );", - - " vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );", - " vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );", - " vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );", - " vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );", - - " mat4 bone = mat4( v1, v2, v3, v4 );", - - " return bone;", - - " }", - - " #else", - - " uniform mat4 boneGlobalMatrices[ MAX_BONES ];", - - " mat4 getBoneMatrix( const in float i ) {", - - " mat4 bone = boneGlobalMatrices[ int(i) ];", - " return bone;", - - " }", - - " #endif", - - "#endif" - - ].join("\n"), - - skinbase_vertex: [ - - "#ifdef USE_SKINNING", - - " mat4 boneMatX = getBoneMatrix( skinIndex.x );", - " mat4 boneMatY = getBoneMatrix( skinIndex.y );", - " mat4 boneMatZ = getBoneMatrix( skinIndex.z );", - " mat4 boneMatW = getBoneMatrix( skinIndex.w );", - - "#endif" - - ].join("\n"), - - skinning_vertex: [ - - "#ifdef USE_SKINNING", - - " #ifdef USE_MORPHTARGETS", - - " vec4 skinVertex = vec4( morphed, 1.0 );", - - " #else", - - " vec4 skinVertex = vec4( position, 1.0 );", - - " #endif", - - " vec4 skinned = boneMatX * skinVertex * skinWeight.x;", - " skinned += boneMatY * skinVertex * skinWeight.y;", - " skinned += boneMatZ * skinVertex * skinWeight.z;", - " skinned += boneMatW * skinVertex * skinWeight.w;", - - "#endif" - - ].join("\n"), - - // MORPHING - - morphtarget_pars_vertex: [ - - "#ifdef USE_MORPHTARGETS", - - " #ifndef USE_MORPHNORMALS", - - " uniform float morphTargetInfluences[ 8 ];", - - " #else", - - " uniform float morphTargetInfluences[ 4 ];", - - " #endif", - - "#endif" - - ].join("\n"), - - morphtarget_vertex: [ - - "#ifdef USE_MORPHTARGETS", - - " vec3 morphed = vec3( 0.0 );", - " morphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];", - " morphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];", - " morphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];", - " morphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];", - - " #ifndef USE_MORPHNORMALS", - - " morphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];", - " morphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];", - " morphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];", - " morphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];", - - " #endif", - - " morphed += position;", - - "#endif" - - ].join("\n"), - - default_vertex : [ - - "vec4 mvPosition;", - - "#ifdef USE_SKINNING", - - " mvPosition = modelViewMatrix * skinned;", - - "#endif", - - "#if !defined( USE_SKINNING ) && defined( USE_MORPHTARGETS )", - - " mvPosition = modelViewMatrix * vec4( morphed, 1.0 );", - - "#endif", - - "#if !defined( USE_SKINNING ) && ! defined( USE_MORPHTARGETS )", - - " mvPosition = modelViewMatrix * vec4( position, 1.0 );", - - "#endif", - - "gl_Position = projectionMatrix * mvPosition;" - - ].join("\n"), - - morphnormal_vertex: [ - - "#ifdef USE_MORPHNORMALS", - - " vec3 morphedNormal = vec3( 0.0 );", - - " morphedNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];", - " morphedNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];", - " morphedNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];", - " morphedNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];", - - " morphedNormal += normal;", - - "#endif" - - ].join("\n"), - - skinnormal_vertex: [ - - "#ifdef USE_SKINNING", - - " mat4 skinMatrix = skinWeight.x * boneMatX;", - " skinMatrix += skinWeight.y * boneMatY;", - " skinMatrix += skinWeight.z * boneMatZ;", - " skinMatrix += skinWeight.w * boneMatW;", - - " #ifdef USE_MORPHNORMALS", - - " vec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );", - - " #else", - - " vec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );", - - " #endif", - - "#endif" - - ].join("\n"), - - defaultnormal_vertex: [ - - "vec3 objectNormal;", - - "#ifdef USE_SKINNING", - - " objectNormal = skinnedNormal.xyz;", - - "#endif", - - "#if !defined( USE_SKINNING ) && defined( USE_MORPHNORMALS )", - - " objectNormal = morphedNormal;", - - "#endif", - - "#if !defined( USE_SKINNING ) && ! defined( USE_MORPHNORMALS )", - - " objectNormal = normal;", - - "#endif", - - "#ifdef FLIP_SIDED", - - " objectNormal = -objectNormal;", - - "#endif", - - "vec3 transformedNormal = normalMatrix * objectNormal;" - - ].join("\n"), - - // SHADOW MAP - - // based on SpiderGL shadow map and Fabien Sanglard's GLSL shadow mapping examples - // http://spidergl.org/example.php?id=6 - // http://fabiensanglard.net/shadowmapping - - shadowmap_pars_fragment: [ - - "#ifdef USE_SHADOWMAP", - - " uniform sampler2D shadowMap[ MAX_SHADOWS ];", - " uniform vec2 shadowMapSize[ MAX_SHADOWS ];", - - " uniform float shadowDarkness[ MAX_SHADOWS ];", - " uniform float shadowBias[ MAX_SHADOWS ];", - - " varying vec4 vShadowCoord[ MAX_SHADOWS ];", - - " float unpackDepth( const in vec4 rgba_depth ) {", - - " const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );", - " float depth = dot( rgba_depth, bit_shift );", - " return depth;", - - " }", - - "#endif" - - ].join("\n"), - - shadowmap_fragment: [ - - "#ifdef USE_SHADOWMAP", - - " #ifdef SHADOWMAP_DEBUG", - - " vec3 frustumColors[3];", - " frustumColors[0] = vec3( 1.0, 0.5, 0.0 );", - " frustumColors[1] = vec3( 0.0, 1.0, 0.8 );", - " frustumColors[2] = vec3( 0.0, 0.5, 1.0 );", - - " #endif", - - " #ifdef SHADOWMAP_CASCADE", - - " int inFrustumCount = 0;", - - " #endif", - - " float fDepth;", - " vec3 shadowColor = vec3( 1.0 );", - - " for( int i = 0; i < MAX_SHADOWS; i ++ ) {", - - " vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;", - - // "if ( something && something )" breaks ATI OpenGL shader compiler - // "if ( all( something, something ) )" using this instead - - " bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );", - " bool inFrustum = all( inFrustumVec );", - - // don't shadow pixels outside of light frustum - // use just first frustum (for cascades) - // don't shadow pixels behind far plane of light frustum - - " #ifdef SHADOWMAP_CASCADE", - - " inFrustumCount += int( inFrustum );", - " bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );", - - " #else", - - " bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );", - - " #endif", - - " bool frustumTest = all( frustumTestVec );", - - " if ( frustumTest ) {", - - " shadowCoord.z += shadowBias[ i ];", - - " #if defined( SHADOWMAP_TYPE_PCF )", - - // Percentage-close filtering - // (9 pixel kernel) - // http://fabiensanglard.net/shadowmappingPCF/ - - " float shadow = 0.0;", - - /* - // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL - // must enroll loop manually - - " for ( float y = -1.25; y <= 1.25; y += 1.25 )", - " for ( float x = -1.25; x <= 1.25; x += 1.25 ) {", - - " vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );", - - // doesn't seem to produce any noticeable visual difference compared to simple "texture2D" lookup - //"vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );", - - " float fDepth = unpackDepth( rgbaDepth );", - - " if ( fDepth < shadowCoord.z )", - " shadow += 1.0;", - - " }", - - " shadow /= 9.0;", - - */ - - " const float shadowDelta = 1.0 / 9.0;", - - " float xPixelOffset = 1.0 / shadowMapSize[ i ].x;", - " float yPixelOffset = 1.0 / shadowMapSize[ i ].y;", - - " float dx0 = -1.25 * xPixelOffset;", - " float dy0 = -1.25 * yPixelOffset;", - " float dx1 = 1.25 * xPixelOffset;", - " float dy1 = 1.25 * yPixelOffset;", - - " fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );", - " if ( fDepth < shadowCoord.z ) shadow += shadowDelta;", - - " fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );", - " if ( fDepth < shadowCoord.z ) shadow += shadowDelta;", - - " fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );", - " if ( fDepth < shadowCoord.z ) shadow += shadowDelta;", - - " fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );", - " if ( fDepth < shadowCoord.z ) shadow += shadowDelta;", - - " fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );", - " if ( fDepth < shadowCoord.z ) shadow += shadowDelta;", - - " fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );", - " if ( fDepth < shadowCoord.z ) shadow += shadowDelta;", - - " fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );", - " if ( fDepth < shadowCoord.z ) shadow += shadowDelta;", - - " fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );", - " if ( fDepth < shadowCoord.z ) shadow += shadowDelta;", - - " fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );", - " if ( fDepth < shadowCoord.z ) shadow += shadowDelta;", - - " shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );", - - " #elif defined( SHADOWMAP_TYPE_PCF_SOFT )", - - // Percentage-close filtering - // (9 pixel kernel) - // http://fabiensanglard.net/shadowmappingPCF/ - - " float shadow = 0.0;", - - " float xPixelOffset = 1.0 / shadowMapSize[ i ].x;", - " float yPixelOffset = 1.0 / shadowMapSize[ i ].y;", - - " float dx0 = -1.0 * xPixelOffset;", - " float dy0 = -1.0 * yPixelOffset;", - " float dx1 = 1.0 * xPixelOffset;", - " float dy1 = 1.0 * yPixelOffset;", - - " mat3 shadowKernel;", - " mat3 depthKernel;", - - " depthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );", - " depthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );", - " depthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );", - " depthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );", - " depthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );", - " depthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );", - " depthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );", - " depthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );", - " depthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );", - - " vec3 shadowZ = vec3( shadowCoord.z );", - " shadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ ));", - " shadowKernel[0] *= vec3(0.25);", - - " shadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ ));", - " shadowKernel[1] *= vec3(0.25);", - - " shadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ ));", - " shadowKernel[2] *= vec3(0.25);", - - " vec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );", - - " shadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );", - " shadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );", - - " vec4 shadowValues;", - " shadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );", - " shadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );", - " shadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );", - " shadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );", - - " shadow = dot( shadowValues, vec4( 1.0 ) );", - - " shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );", - - " #else", - - " vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );", - " float fDepth = unpackDepth( rgbaDepth );", - - " if ( fDepth < shadowCoord.z )", - - // spot with multiple shadows is darker - - " shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );", - - // spot with multiple shadows has the same color as single shadow spot - - //"shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );", - - " #endif", - - " }", - - - " #ifdef SHADOWMAP_DEBUG", - - " #ifdef SHADOWMAP_CASCADE", - - " if ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];", - - " #else", - - " if ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];", - - " #endif", - - " #endif", - - " }", - - " #ifdef GAMMA_OUTPUT", - - " shadowColor *= shadowColor;", - - " #endif", - - " gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;", - - "#endif" - - ].join("\n"), - - shadowmap_pars_vertex: [ - - "#ifdef USE_SHADOWMAP", - - " varying vec4 vShadowCoord[ MAX_SHADOWS ];", - " uniform mat4 shadowMatrix[ MAX_SHADOWS ];", - - "#endif" - - ].join("\n"), - - shadowmap_vertex: [ - - "#ifdef USE_SHADOWMAP", - - " for( int i = 0; i < MAX_SHADOWS; i ++ ) {", - - " vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;", - - " }", - - "#endif" - - ].join("\n"), - - // ALPHATEST - - alphatest_fragment: [ - - "#ifdef ALPHATEST", - - " if ( gl_FragColor.a < ALPHATEST ) discard;", - - "#endif" - - ].join("\n"), - - // LINEAR SPACE - - linear_to_gamma_fragment: [ - - "#ifdef GAMMA_OUTPUT", - - " gl_FragColor.xyz = sqrt( gl_FragColor.xyz );", - - "#endif" - - ].join("\n"), - - // LOGARITHMIC DEPTH BUFFER - // http://outerra.blogspot.com/2012/11/maximizing-depth-buffer-range-and.html - - // WebGL doesn't support gl_FragDepth out of the box, unless the EXT_frag_depth extension is available. On platforms - // without EXT_frag_depth, we have to fall back on linear z-buffer in the fragment shader, which means that some long - // faces close to the camera may have issues. This can be worked around by tesselating the model more finely when - // the camera is near the surface. - - logdepthbuf_pars_vertex: [ - - "#ifdef USE_LOGDEPTHBUF", - - " #ifdef USE_LOGDEPTHBUF_EXT", - - " varying float vFragDepth;", - - " #endif", - - " uniform float logDepthBufFC;", - - "#endif", - - ].join('\n'), - - logdepthbuf_vertex: [ - - "#ifdef USE_LOGDEPTHBUF", - - " gl_Position.z = log2(max(1e-6, gl_Position.w + 1.0)) * logDepthBufFC;", - - " #ifdef USE_LOGDEPTHBUF_EXT", - - " vFragDepth = 1.0 + gl_Position.w;", - - "#else", - - " gl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;", - - " #endif", - - "#endif" - - ].join("\n"), - - logdepthbuf_pars_fragment: [ - - "#ifdef USE_LOGDEPTHBUF", - - " uniform float logDepthBufFC;", - - " #ifdef USE_LOGDEPTHBUF_EXT", - - " #extension GL_EXT_frag_depth : enable", - " varying float vFragDepth;", - - " #endif", - - "#endif" - - ].join('\n'), - - logdepthbuf_fragment: [ - "#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)", - - " gl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;", - - "#endif" - - ].join("\n") - -}; - -/** - * Uniform Utilities - */ - -THREE.UniformsUtils = { - - merge: function ( uniforms ) { - - var u, p, tmp, merged = {}; - - for ( u = 0; u < uniforms.length; u ++ ) { - - tmp = this.clone( uniforms[ u ] ); - - for ( p in tmp ) { - - merged[ p ] = tmp[ p ]; - - } - - } - - return merged; - - }, - - clone: function ( uniforms_src ) { - - var u, p, parameter, parameter_src, uniforms_dst = {}; - - for ( u in uniforms_src ) { - - uniforms_dst[ u ] = {}; - - for ( p in uniforms_src[ u ] ) { - - parameter_src = uniforms_src[ u ][ p ]; - - if ( parameter_src instanceof THREE.Color || - parameter_src instanceof THREE.Vector2 || - parameter_src instanceof THREE.Vector3 || - parameter_src instanceof THREE.Vector4 || - parameter_src instanceof THREE.Matrix4 || - parameter_src instanceof THREE.Texture ) { - - uniforms_dst[ u ][ p ] = parameter_src.clone(); - - } else if ( parameter_src instanceof Array ) { - - uniforms_dst[ u ][ p ] = parameter_src.slice(); - - } else { - - uniforms_dst[ u ][ p ] = parameter_src; - - } - - } - - } - - return uniforms_dst; - - } - -}; -/** - * Uniforms library for shared webgl shaders - */ - -THREE.UniformsLib = { - - common: { - - "diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) }, - "opacity" : { type: "f", value: 1.0 }, - - "map" : { type: "t", value: null }, - "offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, - - "lightMap" : { type: "t", value: null }, - "specularMap" : { type: "t", value: null }, - - "envMap" : { type: "t", value: null }, - "flipEnvMap" : { type: "f", value: -1 }, - "useRefract" : { type: "i", value: 0 }, - "reflectivity" : { type: "f", value: 1.0 }, - "refractionRatio" : { type: "f", value: 0.98 }, - "combine" : { type: "i", value: 0 }, - - "morphTargetInfluences" : { type: "f", value: 0 } - - }, - - bump: { - - "bumpMap" : { type: "t", value: null }, - "bumpScale" : { type: "f", value: 1 } - - }, - - normalmap: { - - "normalMap" : { type: "t", value: null }, - "normalScale" : { type: "v2", value: new THREE.Vector2( 1, 1 ) } - }, - - fog : { - - "fogDensity" : { type: "f", value: 0.00025 }, - "fogNear" : { type: "f", value: 1 }, - "fogFar" : { type: "f", value: 2000 }, - "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) } - - }, - - lights: { - - "ambientLightColor" : { type: "fv", value: [] }, - - "directionalLightDirection" : { type: "fv", value: [] }, - "directionalLightColor" : { type: "fv", value: [] }, - - "hemisphereLightDirection" : { type: "fv", value: [] }, - "hemisphereLightSkyColor" : { type: "fv", value: [] }, - "hemisphereLightGroundColor" : { type: "fv", value: [] }, - - "pointLightColor" : { type: "fv", value: [] }, - "pointLightPosition" : { type: "fv", value: [] }, - "pointLightDistance" : { type: "fv1", value: [] }, - - "spotLightColor" : { type: "fv", value: [] }, - "spotLightPosition" : { type: "fv", value: [] }, - "spotLightDirection" : { type: "fv", value: [] }, - "spotLightDistance" : { type: "fv1", value: [] }, - "spotLightAngleCos" : { type: "fv1", value: [] }, - "spotLightExponent" : { type: "fv1", value: [] } - - }, - - particle: { - - "psColor" : { type: "c", value: new THREE.Color( 0xeeeeee ) }, - "opacity" : { type: "f", value: 1.0 }, - "size" : { type: "f", value: 1.0 }, - "scale" : { type: "f", value: 1.0 }, - "map" : { type: "t", value: null }, - - "fogDensity" : { type: "f", value: 0.00025 }, - "fogNear" : { type: "f", value: 1 }, - "fogFar" : { type: "f", value: 2000 }, - "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) } - - }, - - shadowmap: { - - "shadowMap": { type: "tv", value: [] }, - "shadowMapSize": { type: "v2v", value: [] }, - - "shadowBias" : { type: "fv1", value: [] }, - "shadowDarkness": { type: "fv1", value: [] }, - - "shadowMatrix" : { type: "m4v", value: [] } - - } - -}; -/** - * Webgl Shader Library for three.js - * - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - */ - - -THREE.ShaderLib = { - - 'basic': { - - uniforms: THREE.UniformsUtils.merge( [ - - THREE.UniformsLib[ "common" ], - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "shadowmap" ] - - ] ), - - vertexShader: [ - - THREE.ShaderChunk[ "map_pars_vertex" ], - THREE.ShaderChunk[ "lightmap_pars_vertex" ], - THREE.ShaderChunk[ "envmap_pars_vertex" ], - THREE.ShaderChunk[ "color_pars_vertex" ], - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "skinning_pars_vertex" ], - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "map_vertex" ], - THREE.ShaderChunk[ "lightmap_vertex" ], - THREE.ShaderChunk[ "color_vertex" ], - THREE.ShaderChunk[ "skinbase_vertex" ], - - " #ifdef USE_ENVMAP", - - THREE.ShaderChunk[ "morphnormal_vertex" ], - THREE.ShaderChunk[ "skinnormal_vertex" ], - THREE.ShaderChunk[ "defaultnormal_vertex" ], - - " #endif", - - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "skinning_vertex" ], - THREE.ShaderChunk[ "default_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - THREE.ShaderChunk[ "worldpos_vertex" ], - THREE.ShaderChunk[ "envmap_vertex" ], - THREE.ShaderChunk[ "shadowmap_vertex" ], - - "}" - - ].join("\n"), - - fragmentShader: [ - - "uniform vec3 diffuse;", - "uniform float opacity;", - - THREE.ShaderChunk[ "color_pars_fragment" ], - THREE.ShaderChunk[ "map_pars_fragment" ], - THREE.ShaderChunk[ "lightmap_pars_fragment" ], - THREE.ShaderChunk[ "envmap_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "specularmap_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " gl_FragColor = vec4( diffuse, opacity );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - THREE.ShaderChunk[ "map_fragment" ], - THREE.ShaderChunk[ "alphatest_fragment" ], - THREE.ShaderChunk[ "specularmap_fragment" ], - THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], - THREE.ShaderChunk[ "envmap_fragment" ], - THREE.ShaderChunk[ "shadowmap_fragment" ], - - THREE.ShaderChunk[ "linear_to_gamma_fragment" ], - - THREE.ShaderChunk[ "fog_fragment" ], - - "}" - - ].join("\n") - - }, - - 'lambert': { - - uniforms: THREE.UniformsUtils.merge( [ - - THREE.UniformsLib[ "common" ], - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "lights" ], - THREE.UniformsLib[ "shadowmap" ], - - { - "ambient" : { type: "c", value: new THREE.Color( 0xffffff ) }, - "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) }, - "wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) } - } - - ] ), - - vertexShader: [ - - "#define LAMBERT", - - "varying vec3 vLightFront;", - - "#ifdef DOUBLE_SIDED", - - " varying vec3 vLightBack;", - - "#endif", - - THREE.ShaderChunk[ "map_pars_vertex" ], - THREE.ShaderChunk[ "lightmap_pars_vertex" ], - THREE.ShaderChunk[ "envmap_pars_vertex" ], - THREE.ShaderChunk[ "lights_lambert_pars_vertex" ], - THREE.ShaderChunk[ "color_pars_vertex" ], - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "skinning_pars_vertex" ], - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "map_vertex" ], - THREE.ShaderChunk[ "lightmap_vertex" ], - THREE.ShaderChunk[ "color_vertex" ], - - THREE.ShaderChunk[ "morphnormal_vertex" ], - THREE.ShaderChunk[ "skinbase_vertex" ], - THREE.ShaderChunk[ "skinnormal_vertex" ], - THREE.ShaderChunk[ "defaultnormal_vertex" ], - - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "skinning_vertex" ], - THREE.ShaderChunk[ "default_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - THREE.ShaderChunk[ "worldpos_vertex" ], - THREE.ShaderChunk[ "envmap_vertex" ], - THREE.ShaderChunk[ "lights_lambert_vertex" ], - THREE.ShaderChunk[ "shadowmap_vertex" ], - - "}" - - ].join("\n"), - - fragmentShader: [ - - "uniform float opacity;", - - "varying vec3 vLightFront;", - - "#ifdef DOUBLE_SIDED", - - " varying vec3 vLightBack;", - - "#endif", - - THREE.ShaderChunk[ "color_pars_fragment" ], - THREE.ShaderChunk[ "map_pars_fragment" ], - THREE.ShaderChunk[ "lightmap_pars_fragment" ], - THREE.ShaderChunk[ "envmap_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "specularmap_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " gl_FragColor = vec4( vec3( 1.0 ), opacity );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - THREE.ShaderChunk[ "map_fragment" ], - THREE.ShaderChunk[ "alphatest_fragment" ], - THREE.ShaderChunk[ "specularmap_fragment" ], - - " #ifdef DOUBLE_SIDED", - - //"float isFront = float( gl_FrontFacing );", - //"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;", - - " if ( gl_FrontFacing )", - " gl_FragColor.xyz *= vLightFront;", - " else", - " gl_FragColor.xyz *= vLightBack;", - - " #else", - - " gl_FragColor.xyz *= vLightFront;", - - " #endif", - - THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], - THREE.ShaderChunk[ "envmap_fragment" ], - THREE.ShaderChunk[ "shadowmap_fragment" ], - - THREE.ShaderChunk[ "linear_to_gamma_fragment" ], - - THREE.ShaderChunk[ "fog_fragment" ], - - "}" - - ].join("\n") - - }, - - 'phong': { - - uniforms: THREE.UniformsUtils.merge( [ - - THREE.UniformsLib[ "common" ], - THREE.UniformsLib[ "bump" ], - THREE.UniformsLib[ "normalmap" ], - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "lights" ], - THREE.UniformsLib[ "shadowmap" ], - - { - "ambient" : { type: "c", value: new THREE.Color( 0xffffff ) }, - "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) }, - "specular" : { type: "c", value: new THREE.Color( 0x111111 ) }, - "shininess": { type: "f", value: 30 }, - "wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) } - } - - ] ), - - vertexShader: [ - - "#define PHONG", - - "varying vec3 vViewPosition;", - "varying vec3 vNormal;", - - THREE.ShaderChunk[ "map_pars_vertex" ], - THREE.ShaderChunk[ "lightmap_pars_vertex" ], - THREE.ShaderChunk[ "envmap_pars_vertex" ], - THREE.ShaderChunk[ "lights_phong_pars_vertex" ], - THREE.ShaderChunk[ "color_pars_vertex" ], - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "skinning_pars_vertex" ], - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "map_vertex" ], - THREE.ShaderChunk[ "lightmap_vertex" ], - THREE.ShaderChunk[ "color_vertex" ], - - THREE.ShaderChunk[ "morphnormal_vertex" ], - THREE.ShaderChunk[ "skinbase_vertex" ], - THREE.ShaderChunk[ "skinnormal_vertex" ], - THREE.ShaderChunk[ "defaultnormal_vertex" ], - - " vNormal = normalize( transformedNormal );", - - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "skinning_vertex" ], - THREE.ShaderChunk[ "default_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - " vViewPosition = -mvPosition.xyz;", - - THREE.ShaderChunk[ "worldpos_vertex" ], - THREE.ShaderChunk[ "envmap_vertex" ], - THREE.ShaderChunk[ "lights_phong_vertex" ], - THREE.ShaderChunk[ "shadowmap_vertex" ], - - "}" - - ].join("\n"), - - fragmentShader: [ - - "uniform vec3 diffuse;", - "uniform float opacity;", - - "uniform vec3 ambient;", - "uniform vec3 emissive;", - "uniform vec3 specular;", - "uniform float shininess;", - - THREE.ShaderChunk[ "color_pars_fragment" ], - THREE.ShaderChunk[ "map_pars_fragment" ], - THREE.ShaderChunk[ "lightmap_pars_fragment" ], - THREE.ShaderChunk[ "envmap_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "lights_phong_pars_fragment" ], - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "bumpmap_pars_fragment" ], - THREE.ShaderChunk[ "normalmap_pars_fragment" ], - THREE.ShaderChunk[ "specularmap_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " gl_FragColor = vec4( vec3( 1.0 ), opacity );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - THREE.ShaderChunk[ "map_fragment" ], - THREE.ShaderChunk[ "alphatest_fragment" ], - THREE.ShaderChunk[ "specularmap_fragment" ], - - THREE.ShaderChunk[ "lights_phong_fragment" ], - - THREE.ShaderChunk[ "lightmap_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], - THREE.ShaderChunk[ "envmap_fragment" ], - THREE.ShaderChunk[ "shadowmap_fragment" ], - - THREE.ShaderChunk[ "linear_to_gamma_fragment" ], - - THREE.ShaderChunk[ "fog_fragment" ], - - "}" - - ].join("\n") - - }, - - 'particle_basic': { - - uniforms: THREE.UniformsUtils.merge( [ - - THREE.UniformsLib[ "particle" ], - THREE.UniformsLib[ "shadowmap" ] - - ] ), - - vertexShader: [ - - "uniform float size;", - "uniform float scale;", - - THREE.ShaderChunk[ "color_pars_vertex" ], - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "color_vertex" ], - - " vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", - - " #ifdef USE_SIZEATTENUATION", - " gl_PointSize = size * ( scale / length( mvPosition.xyz ) );", - " #else", - " gl_PointSize = size;", - " #endif", - - " gl_Position = projectionMatrix * mvPosition;", - - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - THREE.ShaderChunk[ "worldpos_vertex" ], - THREE.ShaderChunk[ "shadowmap_vertex" ], - - "}" - - ].join("\n"), - - fragmentShader: [ - - "uniform vec3 psColor;", - "uniform float opacity;", - - THREE.ShaderChunk[ "color_pars_fragment" ], - THREE.ShaderChunk[ "map_particle_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " gl_FragColor = vec4( psColor, opacity );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - THREE.ShaderChunk[ "map_particle_fragment" ], - THREE.ShaderChunk[ "alphatest_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], - THREE.ShaderChunk[ "shadowmap_fragment" ], - THREE.ShaderChunk[ "fog_fragment" ], - - "}" - - ].join("\n") - - }, - - 'dashed': { - - uniforms: THREE.UniformsUtils.merge( [ - - THREE.UniformsLib[ "common" ], - THREE.UniformsLib[ "fog" ], - - { - "scale": { type: "f", value: 1 }, - "dashSize": { type: "f", value: 1 }, - "totalSize": { type: "f", value: 2 } - } - - ] ), - - vertexShader: [ - - "uniform float scale;", - "attribute float lineDistance;", - - "varying float vLineDistance;", - - THREE.ShaderChunk[ "color_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "color_vertex" ], - - " vLineDistance = scale * lineDistance;", - - " vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", - " gl_Position = projectionMatrix * mvPosition;", - - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - "}" - - ].join("\n"), - - fragmentShader: [ - - "uniform vec3 diffuse;", - "uniform float opacity;", - - "uniform float dashSize;", - "uniform float totalSize;", - - "varying float vLineDistance;", - - THREE.ShaderChunk[ "color_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " if ( mod( vLineDistance, totalSize ) > dashSize ) {", - - " discard;", - - " }", - - " gl_FragColor = vec4( diffuse, opacity );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], - THREE.ShaderChunk[ "fog_fragment" ], - - "}" - - ].join("\n") - - }, - - 'depth': { - - uniforms: { - - "mNear": { type: "f", value: 1.0 }, - "mFar" : { type: "f", value: 2000.0 }, - "opacity" : { type: "f", value: 1.0 } - - }, - - vertexShader: [ - - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "default_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - "}" - - ].join("\n"), - - fragmentShader: [ - - "uniform float mNear;", - "uniform float mFar;", - "uniform float opacity;", - - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - - " #ifdef USE_LOGDEPTHBUF_EXT", - - " float depth = gl_FragDepthEXT / gl_FragCoord.w;", - - " #else", - - " float depth = gl_FragCoord.z / gl_FragCoord.w;", - - " #endif", - - " float color = 1.0 - smoothstep( mNear, mFar, depth );", - " gl_FragColor = vec4( vec3( color ), opacity );", - - "}" - - ].join("\n") - - }, - - 'normal': { - - uniforms: { - - "opacity" : { type: "f", value: 1.0 } - - }, - - vertexShader: [ - - "varying vec3 vNormal;", - - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - " vNormal = normalize( normalMatrix * normal );", - - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "default_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - "}" - - ].join("\n"), - - fragmentShader: [ - - "uniform float opacity;", - "varying vec3 vNormal;", - - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - - "}" - - ].join("\n") - - }, - - /* ------------------------------------------------------------------------- - // Normal map shader - // - Blinn-Phong - // - normal + diffuse + specular + AO + displacement + reflection + shadow maps - // - point and directional lights (use with "lights: true" material option) - ------------------------------------------------------------------------- */ - - 'normalmap' : { - - uniforms: THREE.UniformsUtils.merge( [ - - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "lights" ], - THREE.UniformsLib[ "shadowmap" ], - - { - - "enableAO" : { type: "i", value: 0 }, - "enableDiffuse" : { type: "i", value: 0 }, - "enableSpecular" : { type: "i", value: 0 }, - "enableReflection": { type: "i", value: 0 }, - "enableDisplacement": { type: "i", value: 0 }, - - "tDisplacement": { type: "t", value: null }, // must go first as this is vertex texture - "tDiffuse" : { type: "t", value: null }, - "tCube" : { type: "t", value: null }, - "tNormal" : { type: "t", value: null }, - "tSpecular" : { type: "t", value: null }, - "tAO" : { type: "t", value: null }, - - "uNormalScale": { type: "v2", value: new THREE.Vector2( 1, 1 ) }, - - "uDisplacementBias": { type: "f", value: 0.0 }, - "uDisplacementScale": { type: "f", value: 1.0 }, - - "diffuse": { type: "c", value: new THREE.Color( 0xffffff ) }, - "specular": { type: "c", value: new THREE.Color( 0x111111 ) }, - "ambient": { type: "c", value: new THREE.Color( 0xffffff ) }, - "shininess": { type: "f", value: 30 }, - "opacity": { type: "f", value: 1 }, - - "useRefract": { type: "i", value: 0 }, - "refractionRatio": { type: "f", value: 0.98 }, - "reflectivity": { type: "f", value: 0.5 }, - - "uOffset" : { type: "v2", value: new THREE.Vector2( 0, 0 ) }, - "uRepeat" : { type: "v2", value: new THREE.Vector2( 1, 1 ) }, - - "wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) } - - } - - ] ), - - fragmentShader: [ - - "uniform vec3 ambient;", - "uniform vec3 diffuse;", - "uniform vec3 specular;", - "uniform float shininess;", - "uniform float opacity;", - - "uniform bool enableDiffuse;", - "uniform bool enableSpecular;", - "uniform bool enableAO;", - "uniform bool enableReflection;", - - "uniform sampler2D tDiffuse;", - "uniform sampler2D tNormal;", - "uniform sampler2D tSpecular;", - "uniform sampler2D tAO;", - - "uniform samplerCube tCube;", - - "uniform vec2 uNormalScale;", - - "uniform bool useRefract;", - "uniform float refractionRatio;", - "uniform float reflectivity;", - - "varying vec3 vTangent;", - "varying vec3 vBinormal;", - "varying vec3 vNormal;", - "varying vec2 vUv;", - - "uniform vec3 ambientLightColor;", - - "#if MAX_DIR_LIGHTS > 0", - - " uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];", - " uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];", - - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - - " uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];", - " uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];", - " uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];", - - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - - " uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", - " uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", - " uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - - "#endif", - - "#if MAX_SPOT_LIGHTS > 0", - - " uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];", - " uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];", - " uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];", - " uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];", - " uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];", - " uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];", - - "#endif", - - "#ifdef WRAP_AROUND", - - " uniform vec3 wrapRGB;", - - "#endif", - - "varying vec3 vWorldPosition;", - "varying vec3 vViewPosition;", - - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - - " gl_FragColor = vec4( vec3( 1.0 ), opacity );", - - " vec3 specularTex = vec3( 1.0 );", - - " vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;", - " normalTex.xy *= uNormalScale;", - " normalTex = normalize( normalTex );", - - " if( enableDiffuse ) {", - - " #ifdef GAMMA_INPUT", - - " vec4 texelColor = texture2D( tDiffuse, vUv );", - " texelColor.xyz *= texelColor.xyz;", - - " gl_FragColor = gl_FragColor * texelColor;", - - " #else", - - " gl_FragColor = gl_FragColor * texture2D( tDiffuse, vUv );", - - " #endif", - - " }", - - " if( enableAO ) {", - - " #ifdef GAMMA_INPUT", - - " vec4 aoColor = texture2D( tAO, vUv );", - " aoColor.xyz *= aoColor.xyz;", - - " gl_FragColor.xyz = gl_FragColor.xyz * aoColor.xyz;", - - " #else", - - " gl_FragColor.xyz = gl_FragColor.xyz * texture2D( tAO, vUv ).xyz;", - - " #endif", - - " }", - - " if( enableSpecular )", - " specularTex = texture2D( tSpecular, vUv ).xyz;", - - " mat3 tsb = mat3( normalize( vTangent ), normalize( vBinormal ), normalize( vNormal ) );", - " vec3 finalNormal = tsb * normalTex;", - - " #ifdef FLIP_SIDED", - - " finalNormal = -finalNormal;", - - " #endif", - - " vec3 normal = normalize( finalNormal );", - " vec3 viewPosition = normalize( vViewPosition );", - - // point lights - - " #if MAX_POINT_LIGHTS > 0", - - " vec3 pointDiffuse = vec3( 0.0 );", - " vec3 pointSpecular = vec3( 0.0 );", - - " for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", - - " vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", - " vec3 pointVector = lPosition.xyz + vViewPosition.xyz;", - - " float pointDistance = 1.0;", - " if ( pointLightDistance[ i ] > 0.0 )", - " pointDistance = 1.0 - min( ( length( pointVector ) / pointLightDistance[ i ] ), 1.0 );", - - " pointVector = normalize( pointVector );", - - // diffuse - - " #ifdef WRAP_AROUND", - - " float pointDiffuseWeightFull = max( dot( normal, pointVector ), 0.0 );", - " float pointDiffuseWeightHalf = max( 0.5 * dot( normal, pointVector ) + 0.5, 0.0 );", - - " vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );", - - " #else", - - " float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );", - - " #endif", - - " pointDiffuse += pointDistance * pointLightColor[ i ] * diffuse * pointDiffuseWeight;", - - // specular - - " vec3 pointHalfVector = normalize( pointVector + viewPosition );", - " float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );", - " float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );", - - // 2.0 => 2.0001 is hack to work around ANGLE bug - - " float specularNormalization = ( shininess + 2.0001 ) / 8.0;", - - " vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( pointVector, pointHalfVector ), 5.0 );", - " pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;", - - " }", - - " #endif", - - // spot lights - - " #if MAX_SPOT_LIGHTS > 0", - - " vec3 spotDiffuse = vec3( 0.0 );", - " vec3 spotSpecular = vec3( 0.0 );", - - " for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {", - - " vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );", - " vec3 spotVector = lPosition.xyz + vViewPosition.xyz;", - - " float spotDistance = 1.0;", - " if ( spotLightDistance[ i ] > 0.0 )", - " spotDistance = 1.0 - min( ( length( spotVector ) / spotLightDistance[ i ] ), 1.0 );", - - " spotVector = normalize( spotVector );", - - " float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );", - - " if ( spotEffect > spotLightAngleCos[ i ] ) {", - - " spotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );", - - // diffuse - - " #ifdef WRAP_AROUND", - - " float spotDiffuseWeightFull = max( dot( normal, spotVector ), 0.0 );", - " float spotDiffuseWeightHalf = max( 0.5 * dot( normal, spotVector ) + 0.5, 0.0 );", - - " vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );", - - " #else", - - " float spotDiffuseWeight = max( dot( normal, spotVector ), 0.0 );", - - " #endif", - - " spotDiffuse += spotDistance * spotLightColor[ i ] * diffuse * spotDiffuseWeight * spotEffect;", - - // specular - - " vec3 spotHalfVector = normalize( spotVector + viewPosition );", - " float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );", - " float spotSpecularWeight = specularTex.r * max( pow( spotDotNormalHalf, shininess ), 0.0 );", - - // 2.0 => 2.0001 is hack to work around ANGLE bug - - " float specularNormalization = ( shininess + 2.0001 ) / 8.0;", - - " vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( spotVector, spotHalfVector ), 5.0 );", - " spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;", - - " }", - - " }", - - " #endif", - - // directional lights - - " #if MAX_DIR_LIGHTS > 0", - - " vec3 dirDiffuse = vec3( 0.0 );", - " vec3 dirSpecular = vec3( 0.0 );", - - " for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {", - - " vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );", - " vec3 dirVector = normalize( lDirection.xyz );", - - // diffuse - - " #ifdef WRAP_AROUND", - - " float directionalLightWeightingFull = max( dot( normal, dirVector ), 0.0 );", - " float directionalLightWeightingHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );", - - " vec3 dirDiffuseWeight = mix( vec3( directionalLightWeightingFull ), vec3( directionalLightWeightingHalf ), wrapRGB );", - - " #else", - - " float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );", - - " #endif", - - " dirDiffuse += directionalLightColor[ i ] * diffuse * dirDiffuseWeight;", - - // specular - - " vec3 dirHalfVector = normalize( dirVector + viewPosition );", - " float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );", - " float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );", - - // 2.0 => 2.0001 is hack to work around ANGLE bug - - " float specularNormalization = ( shininess + 2.0001 ) / 8.0;", - - " vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );", - " dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;", - - " }", - - " #endif", - - // hemisphere lights - - " #if MAX_HEMI_LIGHTS > 0", - - " vec3 hemiDiffuse = vec3( 0.0 );", - " vec3 hemiSpecular = vec3( 0.0 );" , - - " for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {", - - " vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );", - " vec3 lVector = normalize( lDirection.xyz );", - - // diffuse - - " float dotProduct = dot( normal, lVector );", - " float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;", - - " vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", - - " hemiDiffuse += diffuse * hemiColor;", - - // specular (sky light) - - - " vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );", - " float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;", - " float hemiSpecularWeightSky = specularTex.r * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );", - - // specular (ground light) - - " vec3 lVectorGround = -lVector;", - - " vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );", - " float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;", - " float hemiSpecularWeightGround = specularTex.r * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );", - - " float dotProductGround = dot( normal, lVectorGround );", - - // 2.0 => 2.0001 is hack to work around ANGLE bug - - " float specularNormalization = ( shininess + 2.0001 ) / 8.0;", - - " vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );", - " vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );", - " hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );", - - " }", - - " #endif", - - // all lights contribution summation - - " vec3 totalDiffuse = vec3( 0.0 );", - " vec3 totalSpecular = vec3( 0.0 );", - - " #if MAX_DIR_LIGHTS > 0", - - " totalDiffuse += dirDiffuse;", - " totalSpecular += dirSpecular;", - - " #endif", - - " #if MAX_HEMI_LIGHTS > 0", - - " totalDiffuse += hemiDiffuse;", - " totalSpecular += hemiSpecular;", - - " #endif", - - " #if MAX_POINT_LIGHTS > 0", - - " totalDiffuse += pointDiffuse;", - " totalSpecular += pointSpecular;", - - " #endif", - - " #if MAX_SPOT_LIGHTS > 0", - - " totalDiffuse += spotDiffuse;", - " totalSpecular += spotSpecular;", - - " #endif", - - " #ifdef METAL", - - " gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient + totalSpecular );", - - " #else", - - " gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient ) + totalSpecular;", - - " #endif", - - " if ( enableReflection ) {", - - " vec3 vReflect;", - " vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );", - - " if ( useRefract ) {", - - " vReflect = refract( cameraToVertex, normal, refractionRatio );", - - " } else {", - - " vReflect = reflect( cameraToVertex, normal );", - - " }", - - " vec4 cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );", - - " #ifdef GAMMA_INPUT", - - " cubeColor.xyz *= cubeColor.xyz;", - - " #endif", - - " gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularTex.r * reflectivity );", - - " }", - - THREE.ShaderChunk[ "shadowmap_fragment" ], - THREE.ShaderChunk[ "linear_to_gamma_fragment" ], - THREE.ShaderChunk[ "fog_fragment" ], - - "}" - - ].join("\n"), - - vertexShader: [ - - "attribute vec4 tangent;", - - "uniform vec2 uOffset;", - "uniform vec2 uRepeat;", - - "uniform bool enableDisplacement;", - - "#ifdef VERTEX_TEXTURES", - - " uniform sampler2D tDisplacement;", - " uniform float uDisplacementScale;", - " uniform float uDisplacementBias;", - - "#endif", - - "varying vec3 vTangent;", - "varying vec3 vBinormal;", - "varying vec3 vNormal;", - "varying vec2 vUv;", - - "varying vec3 vWorldPosition;", - "varying vec3 vViewPosition;", - - THREE.ShaderChunk[ "skinning_pars_vertex" ], - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "skinbase_vertex" ], - THREE.ShaderChunk[ "skinnormal_vertex" ], - - // normal, tangent and binormal vectors - - " #ifdef USE_SKINNING", - - " vNormal = normalize( normalMatrix * skinnedNormal.xyz );", - - " vec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );", - " vTangent = normalize( normalMatrix * skinnedTangent.xyz );", - - " #else", - - " vNormal = normalize( normalMatrix * normal );", - " vTangent = normalize( normalMatrix * tangent.xyz );", - - " #endif", - - " vBinormal = normalize( cross( vNormal, vTangent ) * tangent.w );", - - " vUv = uv * uRepeat + uOffset;", - - // displacement mapping - - " vec3 displacedPosition;", - - " #ifdef VERTEX_TEXTURES", - - " if ( enableDisplacement ) {", - - " vec3 dv = texture2D( tDisplacement, uv ).xyz;", - " float df = uDisplacementScale * dv.x + uDisplacementBias;", - " displacedPosition = position + normalize( normal ) * df;", - - " } else {", - - " #ifdef USE_SKINNING", - - " vec4 skinVertex = vec4( position, 1.0 );", - - " vec4 skinned = boneMatX * skinVertex * skinWeight.x;", - " skinned += boneMatY * skinVertex * skinWeight.y;", - " skinned += boneMatZ * skinVertex * skinWeight.z;", - " skinned += boneMatW * skinVertex * skinWeight.w;", - - " displacedPosition = skinned.xyz;", - - " #else", - - " displacedPosition = position;", - - " #endif", - - " }", - - " #else", - - " #ifdef USE_SKINNING", - - " vec4 skinVertex = vec4( position, 1.0 );", - - " vec4 skinned = boneMatX * skinVertex * skinWeight.x;", - " skinned += boneMatY * skinVertex * skinWeight.y;", - " skinned += boneMatZ * skinVertex * skinWeight.z;", - " skinned += boneMatW * skinVertex * skinWeight.w;", - - " displacedPosition = skinned.xyz;", - - " #else", - - " displacedPosition = position;", - - " #endif", - - " #endif", - - // - - " vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );", - " vec4 worldPosition = modelMatrix * vec4( displacedPosition, 1.0 );", - - " gl_Position = projectionMatrix * mvPosition;", - - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - // - - " vWorldPosition = worldPosition.xyz;", - " vViewPosition = -mvPosition.xyz;", - - // shadows - - " #ifdef USE_SHADOWMAP", - - " for( int i = 0; i < MAX_SHADOWS; i ++ ) {", - - " vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;", - - " }", - - " #endif", - - "}" - - ].join("\n") - - }, - - /* ------------------------------------------------------------------------- - // Cube map shader - ------------------------------------------------------------------------- */ - - 'cube': { - - uniforms: { "tCube": { type: "t", value: null }, - "tFlip": { type: "f", value: -1 } }, - - vertexShader: [ - - "varying vec3 vWorldPosition;", - - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - " vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", - " vWorldPosition = worldPosition.xyz;", - - " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", - - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - "}" - - ].join("\n"), - - fragmentShader: [ - - "uniform samplerCube tCube;", - "uniform float tFlip;", - - "varying vec3 vWorldPosition;", - - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - - "}" - - ].join("\n") - - }, - - // Depth encoding into RGBA texture - // based on SpiderGL shadow map example - // http://spidergl.org/example.php?id=6 - // originally from - // http://www.gamedev.net/topic/442138-packing-a-float-into-a-a8r8g8b8-texture-shader/page__whichpage__1%25EF%25BF%25BD - // see also here: - // http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ - - 'depthRGBA': { - - uniforms: {}, - - vertexShader: [ - - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "skinning_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "skinbase_vertex" ], - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "skinning_vertex" ], - THREE.ShaderChunk[ "default_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - "}" - - ].join("\n"), - - fragmentShader: [ - - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "vec4 pack_depth( const in float depth ) {", - - " const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );", - " const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );", - " vec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );", // " vec4 res = fract( depth * bit_shift );", - " res -= res.xxyz * bit_mask;", - " return res;", - - "}", - - "void main() {", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - - " #ifdef USE_LOGDEPTHBUF_EXT", - - " gl_FragData[ 0 ] = pack_depth( gl_FragDepthEXT );", - - " #else", - - " gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );", - - " #endif", - - //"gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z / gl_FragCoord.w );", - //"float z = ( ( gl_FragCoord.z / gl_FragCoord.w ) - 3.0 ) / ( 4000.0 - 3.0 );", - //"gl_FragData[ 0 ] = pack_depth( z );", - //"gl_FragData[ 0 ] = vec4( z, z, z, 1.0 );", - - "}" - - ].join("\n") - - } - -}; - -/** - * @author supereggbert / http://www.paulbrunt.co.uk/ - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author szimek / https://github.com/szimek/ - */ - -THREE.WebGLRenderer = function ( parameters ) { - - console.log( 'THREE.WebGLRenderer', THREE.REVISION ); - - parameters = parameters || {}; - - var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ), - _context = parameters.context !== undefined ? parameters.context : null, - - _precision = parameters.precision !== undefined ? parameters.precision : 'highp', - - _buffers = {}, - - _alpha = parameters.alpha !== undefined ? parameters.alpha : false, - _depth = parameters.depth !== undefined ? parameters.depth : true, - _stencil = parameters.stencil !== undefined ? parameters.stencil : true, - _antialias = parameters.antialias !== undefined ? parameters.antialias : false, - _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true, - _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, - _logarithmicDepthBuffer = parameters.logarithmicDepthBuffer !== undefined ? parameters.logarithmicDepthBuffer : false, - - _clearColor = new THREE.Color( 0x000000 ), - _clearAlpha = 0; - - // public properties - - this.domElement = _canvas; - this.context = null; - this.devicePixelRatio = parameters.devicePixelRatio !== undefined - ? parameters.devicePixelRatio - : self.devicePixelRatio !== undefined - ? self.devicePixelRatio - : 1; - - // clearing - - this.autoClear = true; - this.autoClearColor = true; - this.autoClearDepth = true; - this.autoClearStencil = true; - - // scene graph - - this.sortObjects = true; - this.autoUpdateObjects = true; - - // physically based shading - - this.gammaInput = false; - this.gammaOutput = false; - - // shadow map - - this.shadowMapEnabled = false; - this.shadowMapAutoUpdate = true; - this.shadowMapType = THREE.PCFShadowMap; - this.shadowMapCullFace = THREE.CullFaceFront; - this.shadowMapDebug = false; - this.shadowMapCascade = false; - - // morphs - - this.maxMorphTargets = 8; - this.maxMorphNormals = 4; - - // flags - - this.autoScaleCubemaps = true; - - // custom render plugins - - this.renderPluginsPre = []; - this.renderPluginsPost = []; - - // info - - this.info = { - - memory: { - - programs: 0, - geometries: 0, - textures: 0 - - }, - - render: { - - calls: 0, - vertices: 0, - faces: 0, - points: 0 - - } - - }; - - // internal properties - - var _this = this, - - _programs = [], - - // internal state cache - - _currentProgram = null, - _currentFramebuffer = null, - _currentMaterialId = -1, - _currentGeometryGroupHash = null, - _currentCamera = null, - - _usedTextureUnits = 0, - - // GL state cache - - _oldDoubleSided = -1, - _oldFlipSided = -1, - - _oldBlending = -1, - - _oldBlendEquation = -1, - _oldBlendSrc = -1, - _oldBlendDst = -1, - - _oldDepthTest = -1, - _oldDepthWrite = -1, - - _oldPolygonOffset = null, - _oldPolygonOffsetFactor = null, - _oldPolygonOffsetUnits = null, - - _oldLineWidth = null, - - _viewportX = 0, - _viewportY = 0, - _viewportWidth = _canvas.width, - _viewportHeight = _canvas.height, - _currentWidth = 0, - _currentHeight = 0, - - _newAttributes = new Uint8Array( 16 ), - _enabledAttributes = new Uint8Array( 16 ), - - // frustum - - _frustum = new THREE.Frustum(), - - // camera matrices cache - - _projScreenMatrix = new THREE.Matrix4(), - _projScreenMatrixPS = new THREE.Matrix4(), - - _vector3 = new THREE.Vector3(), - - // light arrays cache - - _direction = new THREE.Vector3(), - - _lightsNeedUpdate = true, - - _lights = { - - ambient: [ 0, 0, 0 ], - directional: { length: 0, colors: new Array(), positions: new Array() }, - point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() }, - spot: { length: 0, colors: new Array(), positions: new Array(), distances: new Array(), directions: new Array(), anglesCos: new Array(), exponents: new Array() }, - hemi: { length: 0, skyColors: new Array(), groundColors: new Array(), positions: new Array() } - - }; - - // initialize - - var _gl; - - var _glExtensionTextureFloat; - var _glExtensionTextureFloatLinear; - var _glExtensionStandardDerivatives; - var _glExtensionTextureFilterAnisotropic; - var _glExtensionCompressedTextureS3TC; - var _glExtensionElementIndexUint; - var _glExtensionFragDepth; - - - initGL(); - - setDefaultGLState(); - - this.context = _gl; - - // GPU capabilities - - var _maxTextures = _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS ); - var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); - var _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE ); - var _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE ); - - var _maxAnisotropy = _glExtensionTextureFilterAnisotropic ? _gl.getParameter( _glExtensionTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT ) : 0; - - var _supportsVertexTextures = ( _maxVertexTextures > 0 ); - var _supportsBoneTextures = _supportsVertexTextures && _glExtensionTextureFloat; - - var _compressedTextureFormats = _glExtensionCompressedTextureS3TC ? _gl.getParameter( _gl.COMPRESSED_TEXTURE_FORMATS ) : []; - - // - - var _vertexShaderPrecisionHighpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.HIGH_FLOAT ); - var _vertexShaderPrecisionMediumpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.MEDIUM_FLOAT ); - var _vertexShaderPrecisionLowpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.LOW_FLOAT ); - - var _fragmentShaderPrecisionHighpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.HIGH_FLOAT ); - var _fragmentShaderPrecisionMediumpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.MEDIUM_FLOAT ); - var _fragmentShaderPrecisionLowpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.LOW_FLOAT ); - - /* - var _vertexShaderPrecisionHighpInt = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.HIGH_INT ); - var _vertexShaderPrecisionMediumpInt = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.MEDIUM_INT ); - var _vertexShaderPrecisionLowpInt = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.LOW_INT ); - - var _fragmentShaderPrecisionHighpInt = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.HIGH_INT ); - var _fragmentShaderPrecisionMediumpInt = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.MEDIUM_INT ); - var _fragmentShaderPrecisionLowpInt = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.LOW_INT ); - */ - - // clamp precision to maximum available - - var highpAvailable = _vertexShaderPrecisionHighpFloat.precision > 0 && _fragmentShaderPrecisionHighpFloat.precision > 0; - var mediumpAvailable = _vertexShaderPrecisionMediumpFloat.precision > 0 && _fragmentShaderPrecisionMediumpFloat.precision > 0; - - if ( _precision === "highp" && ! highpAvailable ) { - - if ( mediumpAvailable ) { - - _precision = "mediump"; - console.warn( "WebGLRenderer: highp not supported, using mediump" ); - - } else { - - _precision = "lowp"; - console.warn( "WebGLRenderer: highp and mediump not supported, using lowp" ); - - } - - } - - if ( _precision === "mediump" && ! mediumpAvailable ) { - - _precision = "lowp"; - console.warn( "WebGLRenderer: mediump not supported, using lowp" ); - - } - - // API - - this.getContext = function () { - - return _gl; - - }; - - this.supportsVertexTextures = function () { - - return _supportsVertexTextures; - - }; - - this.supportsFloatTextures = function () { - - return _glExtensionTextureFloat; - - }; - - this.supportsStandardDerivatives = function () { - - return _glExtensionStandardDerivatives; - - }; - - this.supportsCompressedTextureS3TC = function () { - - return _glExtensionCompressedTextureS3TC; - - }; - - this.getMaxAnisotropy = function () { - - return _maxAnisotropy; - - }; - - this.getPrecision = function () { - - return _precision; - - }; - - this.setSize = function ( width, height, updateStyle ) { - - _canvas.width = width * this.devicePixelRatio; - _canvas.height = height * this.devicePixelRatio; - - if ( updateStyle !== false ) { - - _canvas.style.width = width + 'px'; - _canvas.style.height = height + 'px'; - - } - - this.setViewport( 0, 0, width, height ); - - }; - - this.setViewport = function ( x, y, width, height ) { - - _viewportX = x * this.devicePixelRatio; - _viewportY = y * this.devicePixelRatio; - - _viewportWidth = width * this.devicePixelRatio; - _viewportHeight = height * this.devicePixelRatio; - - _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight ); - - }; - - this.setScissor = function ( x, y, width, height ) { - - _gl.scissor( - x * this.devicePixelRatio, - y * this.devicePixelRatio, - width * this.devicePixelRatio, - height * this.devicePixelRatio - ); - - }; - - this.enableScissorTest = function ( enable ) { - - enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST ); - - }; - - // Clearing - - this.setClearColor = function ( color, alpha ) { - - _clearColor.set( color ); - _clearAlpha = alpha !== undefined ? alpha : 1; - - _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); - - }; - - this.setClearColorHex = function ( hex, alpha ) { - - console.warn( 'DEPRECATED: .setClearColorHex() is being removed. Use .setClearColor() instead.' ); - this.setClearColor( hex, alpha ); - - }; - - this.getClearColor = function () { - - return _clearColor; - - }; - - this.getClearAlpha = function () { - - return _clearAlpha; - - }; - - this.clear = function ( color, depth, stencil ) { - - var bits = 0; - - if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT; - if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT; - if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT; - - _gl.clear( bits ); - - }; - - this.clearColor = function () { - - _gl.clear( _gl.COLOR_BUFFER_BIT ); - - }; - - this.clearDepth = function () { - - _gl.clear( _gl.DEPTH_BUFFER_BIT ); - - }; - - this.clearStencil = function () { - - _gl.clear( _gl.STENCIL_BUFFER_BIT ); - - }; - - this.clearTarget = function ( renderTarget, color, depth, stencil ) { - - this.setRenderTarget( renderTarget ); - this.clear( color, depth, stencil ); - - }; - - // Plugins - - this.addPostPlugin = function ( plugin ) { - - plugin.init( this ); - this.renderPluginsPost.push( plugin ); - - }; - - this.addPrePlugin = function ( plugin ) { - - plugin.init( this ); - this.renderPluginsPre.push( plugin ); - - }; - - // Rendering - - this.updateShadowMap = function ( scene, camera ) { - - _currentProgram = null; - _oldBlending = -1; - _oldDepthTest = -1; - _oldDepthWrite = -1; - _currentGeometryGroupHash = -1; - _currentMaterialId = -1; - _lightsNeedUpdate = true; - _oldDoubleSided = -1; - _oldFlipSided = -1; - - this.shadowMapPlugin.update( scene, camera ); - - }; - - // Internal functions - - // Buffer allocation - - function createParticleBuffers ( geometry ) { - - geometry.__webglVertexBuffer = _gl.createBuffer(); - geometry.__webglColorBuffer = _gl.createBuffer(); - - _this.info.memory.geometries ++; - - }; - - function createLineBuffers ( geometry ) { - - geometry.__webglVertexBuffer = _gl.createBuffer(); - geometry.__webglColorBuffer = _gl.createBuffer(); - geometry.__webglLineDistanceBuffer = _gl.createBuffer(); - - _this.info.memory.geometries ++; - - }; - - function createMeshBuffers ( geometryGroup ) { - - geometryGroup.__webglVertexBuffer = _gl.createBuffer(); - geometryGroup.__webglNormalBuffer = _gl.createBuffer(); - geometryGroup.__webglTangentBuffer = _gl.createBuffer(); - geometryGroup.__webglColorBuffer = _gl.createBuffer(); - geometryGroup.__webglUVBuffer = _gl.createBuffer(); - geometryGroup.__webglUV2Buffer = _gl.createBuffer(); - - geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer(); - geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer(); - - geometryGroup.__webglFaceBuffer = _gl.createBuffer(); - geometryGroup.__webglLineBuffer = _gl.createBuffer(); - - var m, ml; - - if ( geometryGroup.numMorphTargets ) { - - geometryGroup.__webglMorphTargetsBuffers = []; - - for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) { - - geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() ); - - } - - } - - if ( geometryGroup.numMorphNormals ) { - - geometryGroup.__webglMorphNormalsBuffers = []; - - for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) { - - geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() ); - - } - - } - - _this.info.memory.geometries ++; - - }; - - // Events - - var onGeometryDispose = function ( event ) { - - var geometry = event.target; - - geometry.removeEventListener( 'dispose', onGeometryDispose ); - - deallocateGeometry( geometry ); - - }; - - var onTextureDispose = function ( event ) { - - var texture = event.target; - - texture.removeEventListener( 'dispose', onTextureDispose ); - - deallocateTexture( texture ); - - _this.info.memory.textures --; - - - }; - - var onRenderTargetDispose = function ( event ) { - - var renderTarget = event.target; - - renderTarget.removeEventListener( 'dispose', onRenderTargetDispose ); - - deallocateRenderTarget( renderTarget ); - - _this.info.memory.textures --; - - }; - - var onMaterialDispose = function ( event ) { - - var material = event.target; - - material.removeEventListener( 'dispose', onMaterialDispose ); - - deallocateMaterial( material ); - - }; - - // Buffer deallocation - - var deleteBuffers = function ( geometry ) { - - if ( geometry.__webglVertexBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglVertexBuffer ); - if ( geometry.__webglNormalBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglNormalBuffer ); - if ( geometry.__webglTangentBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglTangentBuffer ); - if ( geometry.__webglColorBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglColorBuffer ); - if ( geometry.__webglUVBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglUVBuffer ); - if ( geometry.__webglUV2Buffer !== undefined ) _gl.deleteBuffer( geometry.__webglUV2Buffer ); - - if ( geometry.__webglSkinIndicesBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglSkinIndicesBuffer ); - if ( geometry.__webglSkinWeightsBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglSkinWeightsBuffer ); - - if ( geometry.__webglFaceBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglFaceBuffer ); - if ( geometry.__webglLineBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglLineBuffer ); - - if ( geometry.__webglLineDistanceBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglLineDistanceBuffer ); - // custom attributes - - if ( geometry.__webglCustomAttributesList !== undefined ) { - - for ( var id in geometry.__webglCustomAttributesList ) { - - _gl.deleteBuffer( geometry.__webglCustomAttributesList[ id ].buffer ); - - } - - } - - _this.info.memory.geometries --; - - }; - - var deallocateGeometry = function ( geometry ) { - - geometry.__webglInit = undefined; - - if ( geometry instanceof THREE.BufferGeometry ) { - - var attributes = geometry.attributes; - - for ( var key in attributes ) { - - if ( attributes[ key ].buffer !== undefined ) { - - _gl.deleteBuffer( attributes[ key ].buffer ); - - } - - } - - _this.info.memory.geometries --; - - } else { - - if ( geometry.geometryGroups !== undefined ) { - - for ( var g in geometry.geometryGroups ) { - - var geometryGroup = geometry.geometryGroups[ g ]; - - if ( geometryGroup.numMorphTargets !== undefined ) { - - for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) { - - _gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] ); - - } - - } - - if ( geometryGroup.numMorphNormals !== undefined ) { - - for ( var m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) { - - _gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] ); - - } - - } - - deleteBuffers( geometryGroup ); - - } - - } else { - - deleteBuffers( geometry ); - - } - - } - - }; - - var deallocateTexture = function ( texture ) { - - if ( texture.image && texture.image.__webglTextureCube ) { - - // cube texture - - _gl.deleteTexture( texture.image.__webglTextureCube ); - - } else { - - // 2D texture - - if ( ! texture.__webglInit ) return; - - texture.__webglInit = false; - _gl.deleteTexture( texture.__webglTexture ); - - } - - }; - - var deallocateRenderTarget = function ( renderTarget ) { - - if ( !renderTarget || ! renderTarget.__webglTexture ) return; - - _gl.deleteTexture( renderTarget.__webglTexture ); - - if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) { - - for ( var i = 0; i < 6; i ++ ) { - - _gl.deleteFramebuffer( renderTarget.__webglFramebuffer[ i ] ); - _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer[ i ] ); - - } - - } else { - - _gl.deleteFramebuffer( renderTarget.__webglFramebuffer ); - _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer ); - - } - - }; - - var deallocateMaterial = function ( material ) { - - var program = material.program; - - if ( program === undefined ) return; - - material.program = undefined; - - // only deallocate GL program if this was the last use of shared program - // assumed there is only single copy of any program in the _programs list - // (that's how it's constructed) - - var i, il, programInfo; - var deleteProgram = false; - - for ( i = 0, il = _programs.length; i < il; i ++ ) { - - programInfo = _programs[ i ]; - - if ( programInfo.program === program ) { - - programInfo.usedTimes --; - - if ( programInfo.usedTimes === 0 ) { - - deleteProgram = true; - - } - - break; - - } - - } - - if ( deleteProgram === true ) { - - // avoid using array.splice, this is costlier than creating new array from scratch - - var newPrograms = []; - - for ( i = 0, il = _programs.length; i < il; i ++ ) { - - programInfo = _programs[ i ]; - - if ( programInfo.program !== program ) { - - newPrograms.push( programInfo ); - - } - - } - - _programs = newPrograms; - - _gl.deleteProgram( program ); - - _this.info.memory.programs --; - - } - - }; - - // Buffer initialization - - function initCustomAttributes ( geometry, object ) { - - var nvertices = geometry.vertices.length; - - var material = object.material; - - if ( material.attributes ) { - - if ( geometry.__webglCustomAttributesList === undefined ) { - - geometry.__webglCustomAttributesList = []; - - } - - for ( var a in material.attributes ) { - - var attribute = material.attributes[ a ]; - - if ( !attribute.__webglInitialized || attribute.createUniqueBuffers ) { - - attribute.__webglInitialized = true; - - var size = 1; // "f" and "i" - - if ( attribute.type === "v2" ) size = 2; - else if ( attribute.type === "v3" ) size = 3; - else if ( attribute.type === "v4" ) size = 4; - else if ( attribute.type === "c" ) size = 3; - - attribute.size = size; - - attribute.array = new Float32Array( nvertices * size ); - - attribute.buffer = _gl.createBuffer(); - attribute.buffer.belongsToAttribute = a; - - attribute.needsUpdate = true; - - } - - geometry.__webglCustomAttributesList.push( attribute ); - - } - - } - - }; - - function initParticleBuffers ( geometry, object ) { - - var nvertices = geometry.vertices.length; - - geometry.__vertexArray = new Float32Array( nvertices * 3 ); - geometry.__colorArray = new Float32Array( nvertices * 3 ); - - geometry.__sortArray = []; - - geometry.__webglParticleCount = nvertices; - - initCustomAttributes ( geometry, object ); - - }; - - function initLineBuffers ( geometry, object ) { - - var nvertices = geometry.vertices.length; - - geometry.__vertexArray = new Float32Array( nvertices * 3 ); - geometry.__colorArray = new Float32Array( nvertices * 3 ); - geometry.__lineDistanceArray = new Float32Array( nvertices * 1 ); - - geometry.__webglLineCount = nvertices; - - initCustomAttributes ( geometry, object ); - - }; - - function initMeshBuffers ( geometryGroup, object ) { - - var geometry = object.geometry, - faces3 = geometryGroup.faces3, - - nvertices = faces3.length * 3, - ntris = faces3.length * 1, - nlines = faces3.length * 3, - - material = getBufferMaterial( object, geometryGroup ), - - uvType = bufferGuessUVType( material ), - normalType = bufferGuessNormalType( material ), - vertexColorType = bufferGuessVertexColorType( material ); - - // console.log( "uvType", uvType, "normalType", normalType, "vertexColorType", vertexColorType, object, geometryGroup, material ); - - geometryGroup.__vertexArray = new Float32Array( nvertices * 3 ); - - if ( normalType ) { - - geometryGroup.__normalArray = new Float32Array( nvertices * 3 ); - - } - - if ( geometry.hasTangents ) { - - geometryGroup.__tangentArray = new Float32Array( nvertices * 4 ); - - } - - if ( vertexColorType ) { - - geometryGroup.__colorArray = new Float32Array( nvertices * 3 ); - - } - - if ( uvType ) { - - if ( geometry.faceVertexUvs.length > 0 ) { - - geometryGroup.__uvArray = new Float32Array( nvertices * 2 ); - - } - - if ( geometry.faceVertexUvs.length > 1 ) { - - geometryGroup.__uv2Array = new Float32Array( nvertices * 2 ); - - } - - } - - if ( object.geometry.skinWeights.length && object.geometry.skinIndices.length ) { - - geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 ); - geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 ); - - } - - var UintArray = _glExtensionElementIndexUint !== null && ntris > 21845 ? Uint32Array : Uint16Array; // 65535 / 3 - - geometryGroup.__typeArray = UintArray; - geometryGroup.__faceArray = new UintArray( ntris * 3 ); - geometryGroup.__lineArray = new UintArray( nlines * 2 ); - - var m, ml; - - if ( geometryGroup.numMorphTargets ) { - - geometryGroup.__morphTargetsArrays = []; - - for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) { - - geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) ); - - } - - } - - if ( geometryGroup.numMorphNormals ) { - - geometryGroup.__morphNormalsArrays = []; - - for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) { - - geometryGroup.__morphNormalsArrays.push( new Float32Array( nvertices * 3 ) ); - - } - - } - - geometryGroup.__webglFaceCount = ntris * 3; - geometryGroup.__webglLineCount = nlines * 2; - - - // custom attributes - - if ( material.attributes ) { - - if ( geometryGroup.__webglCustomAttributesList === undefined ) { - - geometryGroup.__webglCustomAttributesList = []; - - } - - for ( var a in material.attributes ) { - - // Do a shallow copy of the attribute object so different geometryGroup chunks use different - // attribute buffers which are correctly indexed in the setMeshBuffers function - - var originalAttribute = material.attributes[ a ]; - - var attribute = {}; - - for ( var property in originalAttribute ) { - - attribute[ property ] = originalAttribute[ property ]; - - } - - if ( !attribute.__webglInitialized || attribute.createUniqueBuffers ) { - - attribute.__webglInitialized = true; - - var size = 1; // "f" and "i" - - if( attribute.type === "v2" ) size = 2; - else if( attribute.type === "v3" ) size = 3; - else if( attribute.type === "v4" ) size = 4; - else if( attribute.type === "c" ) size = 3; - - attribute.size = size; - - attribute.array = new Float32Array( nvertices * size ); - - attribute.buffer = _gl.createBuffer(); - attribute.buffer.belongsToAttribute = a; - - originalAttribute.needsUpdate = true; - attribute.__original = originalAttribute; - - } - - geometryGroup.__webglCustomAttributesList.push( attribute ); - - } - - } - - geometryGroup.__inittedArrays = true; - - }; - - function getBufferMaterial( object, geometryGroup ) { - - return object.material instanceof THREE.MeshFaceMaterial - ? object.material.materials[ geometryGroup.materialIndex ] - : object.material; - - }; - - function materialNeedsSmoothNormals ( material ) { - - return material && material.shading !== undefined && material.shading === THREE.SmoothShading; - - }; - - function bufferGuessNormalType ( material ) { - - // only MeshBasicMaterial and MeshDepthMaterial don't need normals - - if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) { - - return false; - - } - - if ( materialNeedsSmoothNormals( material ) ) { - - return THREE.SmoothShading; - - } else { - - return THREE.FlatShading; - - } - - }; - - function bufferGuessVertexColorType( material ) { - - if ( material.vertexColors ) { - - return material.vertexColors; - - } - - return false; - - }; - - function bufferGuessUVType( material ) { - - // material must use some texture to require uvs - - if ( material.map || - material.lightMap || - material.bumpMap || - material.normalMap || - material.specularMap || - material instanceof THREE.ShaderMaterial ) { - - return true; - - } - - return false; - - }; - - // - - function initDirectBuffers( geometry ) { - - for ( var name in geometry.attributes ) { - - var bufferType = ( name === "index" ) ? _gl.ELEMENT_ARRAY_BUFFER : _gl.ARRAY_BUFFER; - - var attribute = geometry.attributes[ name ]; - attribute.buffer = _gl.createBuffer(); - - _gl.bindBuffer( bufferType, attribute.buffer ); - _gl.bufferData( bufferType, attribute.array, _gl.STATIC_DRAW ); - - } - - } - - // Buffer setting - - function setParticleBuffers ( geometry, hint, object ) { - - var v, c, vertex, offset, index, color, - - vertices = geometry.vertices, - vl = vertices.length, - - colors = geometry.colors, - cl = colors.length, - - vertexArray = geometry.__vertexArray, - colorArray = geometry.__colorArray, - - sortArray = geometry.__sortArray, - - dirtyVertices = geometry.verticesNeedUpdate, - dirtyElements = geometry.elementsNeedUpdate, - dirtyColors = geometry.colorsNeedUpdate, - - customAttributes = geometry.__webglCustomAttributesList, - i, il, - a, ca, cal, value, - customAttribute; - - if ( object.sortParticles ) { - - _projScreenMatrixPS.copy( _projScreenMatrix ); - _projScreenMatrixPS.multiply( object.matrixWorld ); - - for ( v = 0; v < vl; v ++ ) { - - vertex = vertices[ v ]; - - _vector3.copy( vertex ); - _vector3.applyProjection( _projScreenMatrixPS ); - - sortArray[ v ] = [ _vector3.z, v ]; - - } - - sortArray.sort( numericalSort ); - - for ( v = 0; v < vl; v ++ ) { - - vertex = vertices[ sortArray[v][1] ]; - - offset = v * 3; - - vertexArray[ offset ] = vertex.x; - vertexArray[ offset + 1 ] = vertex.y; - vertexArray[ offset + 2 ] = vertex.z; - - } - - for ( c = 0; c < cl; c ++ ) { - - offset = c * 3; - - color = colors[ sortArray[c][1] ]; - - colorArray[ offset ] = color.r; - colorArray[ offset + 1 ] = color.g; - colorArray[ offset + 2 ] = color.b; - - } - - if ( customAttributes ) { - - for ( i = 0, il = customAttributes.length; i < il; i ++ ) { - - customAttribute = customAttributes[ i ]; - - if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue; - - offset = 0; - - cal = customAttribute.value.length; - - if ( customAttribute.size === 1 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - index = sortArray[ ca ][ 1 ]; - - customAttribute.array[ ca ] = customAttribute.value[ index ]; - - } - - } else if ( customAttribute.size === 2 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - index = sortArray[ ca ][ 1 ]; - - value = customAttribute.value[ index ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - - offset += 2; - - } - - } else if ( customAttribute.size === 3 ) { - - if ( customAttribute.type === "c" ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - index = sortArray[ ca ][ 1 ]; - - value = customAttribute.value[ index ]; - - customAttribute.array[ offset ] = value.r; - customAttribute.array[ offset + 1 ] = value.g; - customAttribute.array[ offset + 2 ] = value.b; - - offset += 3; - - } - - } else { - - for ( ca = 0; ca < cal; ca ++ ) { - - index = sortArray[ ca ][ 1 ]; - - value = customAttribute.value[ index ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - - offset += 3; - - } - - } - - } else if ( customAttribute.size === 4 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - index = sortArray[ ca ][ 1 ]; - - value = customAttribute.value[ index ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - customAttribute.array[ offset + 3 ] = value.w; - - offset += 4; - - } - - } - - } - - } - - } else { - - if ( dirtyVertices ) { - - for ( v = 0; v < vl; v ++ ) { - - vertex = vertices[ v ]; - - offset = v * 3; - - vertexArray[ offset ] = vertex.x; - vertexArray[ offset + 1 ] = vertex.y; - vertexArray[ offset + 2 ] = vertex.z; - - } - - } - - if ( dirtyColors ) { - - for ( c = 0; c < cl; c ++ ) { - - color = colors[ c ]; - - offset = c * 3; - - colorArray[ offset ] = color.r; - colorArray[ offset + 1 ] = color.g; - colorArray[ offset + 2 ] = color.b; - - } - - } - - if ( customAttributes ) { - - for ( i = 0, il = customAttributes.length; i < il; i ++ ) { - - customAttribute = customAttributes[ i ]; - - if ( customAttribute.needsUpdate && - ( customAttribute.boundTo === undefined || - customAttribute.boundTo === "vertices") ) { - - cal = customAttribute.value.length; - - offset = 0; - - if ( customAttribute.size === 1 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - customAttribute.array[ ca ] = customAttribute.value[ ca ]; - - } - - } else if ( customAttribute.size === 2 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - - offset += 2; - - } - - } else if ( customAttribute.size === 3 ) { - - if ( customAttribute.type === "c" ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.r; - customAttribute.array[ offset + 1 ] = value.g; - customAttribute.array[ offset + 2 ] = value.b; - - offset += 3; - - } - - } else { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - - offset += 3; - - } - - } - - } else if ( customAttribute.size === 4 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - customAttribute.array[ offset + 3 ] = value.w; - - offset += 4; - - } - - } - - } - - } - - } - - } - - if ( dirtyVertices || object.sortParticles ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); - - } - - if ( dirtyColors || object.sortParticles ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); - - } - - if ( customAttributes ) { - - for ( i = 0, il = customAttributes.length; i < il; i ++ ) { - - customAttribute = customAttributes[ i ]; - - if ( customAttribute.needsUpdate || object.sortParticles ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint ); - - } - - } - - } - - } - - function setLineBuffers ( geometry, hint ) { - - var v, c, d, vertex, offset, color, - - vertices = geometry.vertices, - colors = geometry.colors, - lineDistances = geometry.lineDistances, - - vl = vertices.length, - cl = colors.length, - dl = lineDistances.length, - - vertexArray = geometry.__vertexArray, - colorArray = geometry.__colorArray, - lineDistanceArray = geometry.__lineDistanceArray, - - dirtyVertices = geometry.verticesNeedUpdate, - dirtyColors = geometry.colorsNeedUpdate, - dirtyLineDistances = geometry.lineDistancesNeedUpdate, - - customAttributes = geometry.__webglCustomAttributesList, - - i, il, - a, ca, cal, value, - customAttribute; - - if ( dirtyVertices ) { - - for ( v = 0; v < vl; v ++ ) { - - vertex = vertices[ v ]; - - offset = v * 3; - - vertexArray[ offset ] = vertex.x; - vertexArray[ offset + 1 ] = vertex.y; - vertexArray[ offset + 2 ] = vertex.z; - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); - - } - - if ( dirtyColors ) { - - for ( c = 0; c < cl; c ++ ) { - - color = colors[ c ]; - - offset = c * 3; - - colorArray[ offset ] = color.r; - colorArray[ offset + 1 ] = color.g; - colorArray[ offset + 2 ] = color.b; - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); - - } - - if ( dirtyLineDistances ) { - - for ( d = 0; d < dl; d ++ ) { - - lineDistanceArray[ d ] = lineDistances[ d ]; - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglLineDistanceBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, lineDistanceArray, hint ); - - } - - if ( customAttributes ) { - - for ( i = 0, il = customAttributes.length; i < il; i ++ ) { - - customAttribute = customAttributes[ i ]; - - if ( customAttribute.needsUpdate && - ( customAttribute.boundTo === undefined || - customAttribute.boundTo === "vertices" ) ) { - - offset = 0; - - cal = customAttribute.value.length; - - if ( customAttribute.size === 1 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - customAttribute.array[ ca ] = customAttribute.value[ ca ]; - - } - - } else if ( customAttribute.size === 2 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - - offset += 2; - - } - - } else if ( customAttribute.size === 3 ) { - - if ( customAttribute.type === "c" ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.r; - customAttribute.array[ offset + 1 ] = value.g; - customAttribute.array[ offset + 2 ] = value.b; - - offset += 3; - - } - - } else { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - - offset += 3; - - } - - } - - } else if ( customAttribute.size === 4 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - customAttribute.array[ offset + 3 ] = value.w; - - offset += 4; - - } - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint ); - - } - - } - - } - - } - - function setMeshBuffers( geometryGroup, object, hint, dispose, material ) { - - if ( ! geometryGroup.__inittedArrays ) { - - return; - - } - - var normalType = bufferGuessNormalType( material ), - vertexColorType = bufferGuessVertexColorType( material ), - uvType = bufferGuessUVType( material ), - - needsSmoothNormals = ( normalType === THREE.SmoothShading ); - - var f, fl, fi, face, - vertexNormals, faceNormal, normal, - vertexColors, faceColor, - vertexTangents, - uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4, - c1, c2, c3, c4, - sw1, sw2, sw3, sw4, - si1, si2, si3, si4, - sa1, sa2, sa3, sa4, - sb1, sb2, sb3, sb4, - m, ml, i, il, - vn, uvi, uv2i, - vk, vkl, vka, - nka, chf, faceVertexNormals, - a, - - vertexIndex = 0, - - offset = 0, - offset_uv = 0, - offset_uv2 = 0, - offset_face = 0, - offset_normal = 0, - offset_tangent = 0, - offset_line = 0, - offset_color = 0, - offset_skin = 0, - offset_morphTarget = 0, - offset_custom = 0, - offset_customSrc = 0, - - value, - - vertexArray = geometryGroup.__vertexArray, - uvArray = geometryGroup.__uvArray, - uv2Array = geometryGroup.__uv2Array, - normalArray = geometryGroup.__normalArray, - tangentArray = geometryGroup.__tangentArray, - colorArray = geometryGroup.__colorArray, - - skinIndexArray = geometryGroup.__skinIndexArray, - skinWeightArray = geometryGroup.__skinWeightArray, - - morphTargetsArrays = geometryGroup.__morphTargetsArrays, - morphNormalsArrays = geometryGroup.__morphNormalsArrays, - - customAttributes = geometryGroup.__webglCustomAttributesList, - customAttribute, - - faceArray = geometryGroup.__faceArray, - lineArray = geometryGroup.__lineArray, - - geometry = object.geometry, // this is shared for all chunks - - dirtyVertices = geometry.verticesNeedUpdate, - dirtyElements = geometry.elementsNeedUpdate, - dirtyUvs = geometry.uvsNeedUpdate, - dirtyNormals = geometry.normalsNeedUpdate, - dirtyTangents = geometry.tangentsNeedUpdate, - dirtyColors = geometry.colorsNeedUpdate, - dirtyMorphTargets = geometry.morphTargetsNeedUpdate, - - vertices = geometry.vertices, - chunk_faces3 = geometryGroup.faces3, - obj_faces = geometry.faces, - - obj_uvs = geometry.faceVertexUvs[ 0 ], - obj_uvs2 = geometry.faceVertexUvs[ 1 ], - - obj_colors = geometry.colors, - - obj_skinIndices = geometry.skinIndices, - obj_skinWeights = geometry.skinWeights, - - morphTargets = geometry.morphTargets, - morphNormals = geometry.morphNormals; - - if ( dirtyVertices ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - face = obj_faces[ chunk_faces3[ f ] ]; - - v1 = vertices[ face.a ]; - v2 = vertices[ face.b ]; - v3 = vertices[ face.c ]; - - vertexArray[ offset ] = v1.x; - vertexArray[ offset + 1 ] = v1.y; - vertexArray[ offset + 2 ] = v1.z; - - vertexArray[ offset + 3 ] = v2.x; - vertexArray[ offset + 4 ] = v2.y; - vertexArray[ offset + 5 ] = v2.z; - - vertexArray[ offset + 6 ] = v3.x; - vertexArray[ offset + 7 ] = v3.y; - vertexArray[ offset + 8 ] = v3.z; - - offset += 9; - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); - - } - - if ( dirtyMorphTargets ) { - - for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) { - - offset_morphTarget = 0; - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - chf = chunk_faces3[ f ]; - face = obj_faces[ chf ]; - - // morph positions - - v1 = morphTargets[ vk ].vertices[ face.a ]; - v2 = morphTargets[ vk ].vertices[ face.b ]; - v3 = morphTargets[ vk ].vertices[ face.c ]; - - vka = morphTargetsArrays[ vk ]; - - vka[ offset_morphTarget ] = v1.x; - vka[ offset_morphTarget + 1 ] = v1.y; - vka[ offset_morphTarget + 2 ] = v1.z; - - vka[ offset_morphTarget + 3 ] = v2.x; - vka[ offset_morphTarget + 4 ] = v2.y; - vka[ offset_morphTarget + 5 ] = v2.z; - - vka[ offset_morphTarget + 6 ] = v3.x; - vka[ offset_morphTarget + 7 ] = v3.y; - vka[ offset_morphTarget + 8 ] = v3.z; - - // morph normals - - if ( material.morphNormals ) { - - if ( needsSmoothNormals ) { - - faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ]; - - n1 = faceVertexNormals.a; - n2 = faceVertexNormals.b; - n3 = faceVertexNormals.c; - - } else { - - n1 = morphNormals[ vk ].faceNormals[ chf ]; - n2 = n1; - n3 = n1; - - } - - nka = morphNormalsArrays[ vk ]; - - nka[ offset_morphTarget ] = n1.x; - nka[ offset_morphTarget + 1 ] = n1.y; - nka[ offset_morphTarget + 2 ] = n1.z; - - nka[ offset_morphTarget + 3 ] = n2.x; - nka[ offset_morphTarget + 4 ] = n2.y; - nka[ offset_morphTarget + 5 ] = n2.z; - - nka[ offset_morphTarget + 6 ] = n3.x; - nka[ offset_morphTarget + 7 ] = n3.y; - nka[ offset_morphTarget + 8 ] = n3.z; - - } - - // - - offset_morphTarget += 9; - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ vk ] ); - _gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint ); - - if ( material.morphNormals ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ vk ] ); - _gl.bufferData( _gl.ARRAY_BUFFER, morphNormalsArrays[ vk ], hint ); - - } - - } - - } - - if ( obj_skinWeights.length ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - face = obj_faces[ chunk_faces3[ f ] ]; - - // weights - - sw1 = obj_skinWeights[ face.a ]; - sw2 = obj_skinWeights[ face.b ]; - sw3 = obj_skinWeights[ face.c ]; - - skinWeightArray[ offset_skin ] = sw1.x; - skinWeightArray[ offset_skin + 1 ] = sw1.y; - skinWeightArray[ offset_skin + 2 ] = sw1.z; - skinWeightArray[ offset_skin + 3 ] = sw1.w; - - skinWeightArray[ offset_skin + 4 ] = sw2.x; - skinWeightArray[ offset_skin + 5 ] = sw2.y; - skinWeightArray[ offset_skin + 6 ] = sw2.z; - skinWeightArray[ offset_skin + 7 ] = sw2.w; - - skinWeightArray[ offset_skin + 8 ] = sw3.x; - skinWeightArray[ offset_skin + 9 ] = sw3.y; - skinWeightArray[ offset_skin + 10 ] = sw3.z; - skinWeightArray[ offset_skin + 11 ] = sw3.w; - - // indices - - si1 = obj_skinIndices[ face.a ]; - si2 = obj_skinIndices[ face.b ]; - si3 = obj_skinIndices[ face.c ]; - - skinIndexArray[ offset_skin ] = si1.x; - skinIndexArray[ offset_skin + 1 ] = si1.y; - skinIndexArray[ offset_skin + 2 ] = si1.z; - skinIndexArray[ offset_skin + 3 ] = si1.w; - - skinIndexArray[ offset_skin + 4 ] = si2.x; - skinIndexArray[ offset_skin + 5 ] = si2.y; - skinIndexArray[ offset_skin + 6 ] = si2.z; - skinIndexArray[ offset_skin + 7 ] = si2.w; - - skinIndexArray[ offset_skin + 8 ] = si3.x; - skinIndexArray[ offset_skin + 9 ] = si3.y; - skinIndexArray[ offset_skin + 10 ] = si3.z; - skinIndexArray[ offset_skin + 11 ] = si3.w; - - offset_skin += 12; - - } - - if ( offset_skin > 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint ); - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint ); - - } - - } - - if ( dirtyColors && vertexColorType ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - face = obj_faces[ chunk_faces3[ f ] ]; - - vertexColors = face.vertexColors; - faceColor = face.color; - - if ( vertexColors.length === 3 && vertexColorType === THREE.VertexColors ) { - - c1 = vertexColors[ 0 ]; - c2 = vertexColors[ 1 ]; - c3 = vertexColors[ 2 ]; - - } else { - - c1 = faceColor; - c2 = faceColor; - c3 = faceColor; - - } - - colorArray[ offset_color ] = c1.r; - colorArray[ offset_color + 1 ] = c1.g; - colorArray[ offset_color + 2 ] = c1.b; - - colorArray[ offset_color + 3 ] = c2.r; - colorArray[ offset_color + 4 ] = c2.g; - colorArray[ offset_color + 5 ] = c2.b; - - colorArray[ offset_color + 6 ] = c3.r; - colorArray[ offset_color + 7 ] = c3.g; - colorArray[ offset_color + 8 ] = c3.b; - - offset_color += 9; - - } - - if ( offset_color > 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); - - } - - } - - if ( dirtyTangents && geometry.hasTangents ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - face = obj_faces[ chunk_faces3[ f ] ]; - - vertexTangents = face.vertexTangents; - - t1 = vertexTangents[ 0 ]; - t2 = vertexTangents[ 1 ]; - t3 = vertexTangents[ 2 ]; - - tangentArray[ offset_tangent ] = t1.x; - tangentArray[ offset_tangent + 1 ] = t1.y; - tangentArray[ offset_tangent + 2 ] = t1.z; - tangentArray[ offset_tangent + 3 ] = t1.w; - - tangentArray[ offset_tangent + 4 ] = t2.x; - tangentArray[ offset_tangent + 5 ] = t2.y; - tangentArray[ offset_tangent + 6 ] = t2.z; - tangentArray[ offset_tangent + 7 ] = t2.w; - - tangentArray[ offset_tangent + 8 ] = t3.x; - tangentArray[ offset_tangent + 9 ] = t3.y; - tangentArray[ offset_tangent + 10 ] = t3.z; - tangentArray[ offset_tangent + 11 ] = t3.w; - - offset_tangent += 12; - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint ); - - } - - if ( dirtyNormals && normalType ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - face = obj_faces[ chunk_faces3[ f ] ]; - - vertexNormals = face.vertexNormals; - faceNormal = face.normal; - - if ( vertexNormals.length === 3 && needsSmoothNormals ) { - - for ( i = 0; i < 3; i ++ ) { - - vn = vertexNormals[ i ]; - - normalArray[ offset_normal ] = vn.x; - normalArray[ offset_normal + 1 ] = vn.y; - normalArray[ offset_normal + 2 ] = vn.z; - - offset_normal += 3; - - } - - } else { - - for ( i = 0; i < 3; i ++ ) { - - normalArray[ offset_normal ] = faceNormal.x; - normalArray[ offset_normal + 1 ] = faceNormal.y; - normalArray[ offset_normal + 2 ] = faceNormal.z; - - offset_normal += 3; - - } - - } - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint ); - - } - - if ( dirtyUvs && obj_uvs && uvType ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - fi = chunk_faces3[ f ]; - - uv = obj_uvs[ fi ]; - - if ( uv === undefined ) continue; - - for ( i = 0; i < 3; i ++ ) { - - uvi = uv[ i ]; - - uvArray[ offset_uv ] = uvi.x; - uvArray[ offset_uv + 1 ] = uvi.y; - - offset_uv += 2; - - } - - } - - if ( offset_uv > 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint ); - - } - - } - - if ( dirtyUvs && obj_uvs2 && uvType ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - fi = chunk_faces3[ f ]; - - uv2 = obj_uvs2[ fi ]; - - if ( uv2 === undefined ) continue; - - for ( i = 0; i < 3; i ++ ) { - - uv2i = uv2[ i ]; - - uv2Array[ offset_uv2 ] = uv2i.x; - uv2Array[ offset_uv2 + 1 ] = uv2i.y; - - offset_uv2 += 2; - - } - - } - - if ( offset_uv2 > 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint ); - - } - - } - - if ( dirtyElements ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - faceArray[ offset_face ] = vertexIndex; - faceArray[ offset_face + 1 ] = vertexIndex + 1; - faceArray[ offset_face + 2 ] = vertexIndex + 2; - - offset_face += 3; - - lineArray[ offset_line ] = vertexIndex; - lineArray[ offset_line + 1 ] = vertexIndex + 1; - - lineArray[ offset_line + 2 ] = vertexIndex; - lineArray[ offset_line + 3 ] = vertexIndex + 2; - - lineArray[ offset_line + 4 ] = vertexIndex + 1; - lineArray[ offset_line + 5 ] = vertexIndex + 2; - - offset_line += 6; - - vertexIndex += 3; - - } - - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer ); - _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint ); - - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer ); - _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint ); - - } - - if ( customAttributes ) { - - for ( i = 0, il = customAttributes.length; i < il; i ++ ) { - - customAttribute = customAttributes[ i ]; - - if ( ! customAttribute.__original.needsUpdate ) continue; - - offset_custom = 0; - offset_customSrc = 0; - - if ( customAttribute.size === 1 ) { - - if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - face = obj_faces[ chunk_faces3[ f ] ]; - - customAttribute.array[ offset_custom ] = customAttribute.value[ face.a ]; - customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ]; - customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ]; - - offset_custom += 3; - - } - - } else if ( customAttribute.boundTo === "faces" ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - value = customAttribute.value[ chunk_faces3[ f ] ]; - - customAttribute.array[ offset_custom ] = value; - customAttribute.array[ offset_custom + 1 ] = value; - customAttribute.array[ offset_custom + 2 ] = value; - - offset_custom += 3; - - } - - } - - } else if ( customAttribute.size === 2 ) { - - if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - face = obj_faces[ chunk_faces3[ f ] ]; - - v1 = customAttribute.value[ face.a ]; - v2 = customAttribute.value[ face.b ]; - v3 = customAttribute.value[ face.c ]; - - customAttribute.array[ offset_custom ] = v1.x; - customAttribute.array[ offset_custom + 1 ] = v1.y; - - customAttribute.array[ offset_custom + 2 ] = v2.x; - customAttribute.array[ offset_custom + 3 ] = v2.y; - - customAttribute.array[ offset_custom + 4 ] = v3.x; - customAttribute.array[ offset_custom + 5 ] = v3.y; - - offset_custom += 6; - - } - - } else if ( customAttribute.boundTo === "faces" ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - value = customAttribute.value[ chunk_faces3[ f ] ]; - - v1 = value; - v2 = value; - v3 = value; - - customAttribute.array[ offset_custom ] = v1.x; - customAttribute.array[ offset_custom + 1 ] = v1.y; - - customAttribute.array[ offset_custom + 2 ] = v2.x; - customAttribute.array[ offset_custom + 3 ] = v2.y; - - customAttribute.array[ offset_custom + 4 ] = v3.x; - customAttribute.array[ offset_custom + 5 ] = v3.y; - - offset_custom += 6; - - } - - } - - } else if ( customAttribute.size === 3 ) { - - var pp; - - if ( customAttribute.type === "c" ) { - - pp = [ "r", "g", "b" ]; - - } else { - - pp = [ "x", "y", "z" ]; - - } - - if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - face = obj_faces[ chunk_faces3[ f ] ]; - - v1 = customAttribute.value[ face.a ]; - v2 = customAttribute.value[ face.b ]; - v3 = customAttribute.value[ face.c ]; - - customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ]; - customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ]; - customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ]; - - customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ]; - customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ]; - customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ]; - - customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ]; - customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ]; - customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ]; - - offset_custom += 9; - - } - - } else if ( customAttribute.boundTo === "faces" ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - value = customAttribute.value[ chunk_faces3[ f ] ]; - - v1 = value; - v2 = value; - v3 = value; - - customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ]; - customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ]; - customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ]; - - customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ]; - customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ]; - customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ]; - - customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ]; - customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ]; - customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ]; - - offset_custom += 9; - - } - - } else if ( customAttribute.boundTo === "faceVertices" ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - value = customAttribute.value[ chunk_faces3[ f ] ]; - - v1 = value[ 0 ]; - v2 = value[ 1 ]; - v3 = value[ 2 ]; - - customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ]; - customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ]; - customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ]; - - customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ]; - customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ]; - customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ]; - - customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ]; - customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ]; - customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ]; - - offset_custom += 9; - - } - - } - - } else if ( customAttribute.size === 4 ) { - - if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - face = obj_faces[ chunk_faces3[ f ] ]; - - v1 = customAttribute.value[ face.a ]; - v2 = customAttribute.value[ face.b ]; - v3 = customAttribute.value[ face.c ]; - - customAttribute.array[ offset_custom ] = v1.x; - customAttribute.array[ offset_custom + 1 ] = v1.y; - customAttribute.array[ offset_custom + 2 ] = v1.z; - customAttribute.array[ offset_custom + 3 ] = v1.w; - - customAttribute.array[ offset_custom + 4 ] = v2.x; - customAttribute.array[ offset_custom + 5 ] = v2.y; - customAttribute.array[ offset_custom + 6 ] = v2.z; - customAttribute.array[ offset_custom + 7 ] = v2.w; - - customAttribute.array[ offset_custom + 8 ] = v3.x; - customAttribute.array[ offset_custom + 9 ] = v3.y; - customAttribute.array[ offset_custom + 10 ] = v3.z; - customAttribute.array[ offset_custom + 11 ] = v3.w; - - offset_custom += 12; - - } - - } else if ( customAttribute.boundTo === "faces" ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - value = customAttribute.value[ chunk_faces3[ f ] ]; - - v1 = value; - v2 = value; - v3 = value; - - customAttribute.array[ offset_custom ] = v1.x; - customAttribute.array[ offset_custom + 1 ] = v1.y; - customAttribute.array[ offset_custom + 2 ] = v1.z; - customAttribute.array[ offset_custom + 3 ] = v1.w; - - customAttribute.array[ offset_custom + 4 ] = v2.x; - customAttribute.array[ offset_custom + 5 ] = v2.y; - customAttribute.array[ offset_custom + 6 ] = v2.z; - customAttribute.array[ offset_custom + 7 ] = v2.w; - - customAttribute.array[ offset_custom + 8 ] = v3.x; - customAttribute.array[ offset_custom + 9 ] = v3.y; - customAttribute.array[ offset_custom + 10 ] = v3.z; - customAttribute.array[ offset_custom + 11 ] = v3.w; - - offset_custom += 12; - - } - - } else if ( customAttribute.boundTo === "faceVertices" ) { - - for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) { - - value = customAttribute.value[ chunk_faces3[ f ] ]; - - v1 = value[ 0 ]; - v2 = value[ 1 ]; - v3 = value[ 2 ]; - - customAttribute.array[ offset_custom ] = v1.x; - customAttribute.array[ offset_custom + 1 ] = v1.y; - customAttribute.array[ offset_custom + 2 ] = v1.z; - customAttribute.array[ offset_custom + 3 ] = v1.w; - - customAttribute.array[ offset_custom + 4 ] = v2.x; - customAttribute.array[ offset_custom + 5 ] = v2.y; - customAttribute.array[ offset_custom + 6 ] = v2.z; - customAttribute.array[ offset_custom + 7 ] = v2.w; - - customAttribute.array[ offset_custom + 8 ] = v3.x; - customAttribute.array[ offset_custom + 9 ] = v3.y; - customAttribute.array[ offset_custom + 10 ] = v3.z; - customAttribute.array[ offset_custom + 11 ] = v3.w; - - offset_custom += 12; - - } - - } - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint ); - - } - - } - - if ( dispose ) { - - delete geometryGroup.__inittedArrays; - delete geometryGroup.__colorArray; - delete geometryGroup.__normalArray; - delete geometryGroup.__tangentArray; - delete geometryGroup.__uvArray; - delete geometryGroup.__uv2Array; - delete geometryGroup.__faceArray; - delete geometryGroup.__vertexArray; - delete geometryGroup.__lineArray; - delete geometryGroup.__skinIndexArray; - delete geometryGroup.__skinWeightArray; - - } - - }; - - function setDirectBuffers( geometry, hint ) { - - var attributes = geometry.attributes; - - var attributeName, attributeItem; - - for ( attributeName in attributes ) { - - attributeItem = attributes[ attributeName ]; - - if ( attributeItem.needsUpdate ) { - - if ( attributeName === 'index' ) { - - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attributeItem.buffer ); - _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, attributeItem.array, hint ); - - } else { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, attributeItem.array, hint ); - - } - - attributeItem.needsUpdate = false; - - } - - } - - } - - // Buffer rendering - - this.renderBufferImmediate = function ( object, program, material ) { - - initAttributes(); - - if ( object.hasPositions && ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer(); - if ( object.hasNormals && ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer(); - if ( object.hasUvs && ! object.__webglUvBuffer ) object.__webglUvBuffer = _gl.createBuffer(); - if ( object.hasColors && ! object.__webglColorBuffer ) object.__webglColorBuffer = _gl.createBuffer(); - - if ( object.hasPositions ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.position ); - _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 ); - - } - - if ( object.hasNormals ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer ); - - if ( material.shading === THREE.FlatShading ) { - - var nx, ny, nz, - nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz, - normalArray, - i, il = object.count * 3; - - for( i = 0; i < il; i += 9 ) { - - normalArray = object.normalArray; - - nax = normalArray[ i ]; - nay = normalArray[ i + 1 ]; - naz = normalArray[ i + 2 ]; - - nbx = normalArray[ i + 3 ]; - nby = normalArray[ i + 4 ]; - nbz = normalArray[ i + 5 ]; - - ncx = normalArray[ i + 6 ]; - ncy = normalArray[ i + 7 ]; - ncz = normalArray[ i + 8 ]; - - nx = ( nax + nbx + ncx ) / 3; - ny = ( nay + nby + ncy ) / 3; - nz = ( naz + nbz + ncz ) / 3; - - normalArray[ i ] = nx; - normalArray[ i + 1 ] = ny; - normalArray[ i + 2 ] = nz; - - normalArray[ i + 3 ] = nx; - normalArray[ i + 4 ] = ny; - normalArray[ i + 5 ] = nz; - - normalArray[ i + 6 ] = nx; - normalArray[ i + 7 ] = ny; - normalArray[ i + 8 ] = nz; - - } - - } - - _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.normal ); - _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 ); - - } - - if ( object.hasUvs && material.map ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglUvBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.uv ); - _gl.vertexAttribPointer( program.attributes.uv, 2, _gl.FLOAT, false, 0, 0 ); - - } - - if ( object.hasColors && material.vertexColors !== THREE.NoColors ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglColorBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW ); - enableAttribute( program.attributes.color ); - _gl.vertexAttribPointer( program.attributes.color, 3, _gl.FLOAT, false, 0, 0 ); - - } - - disableUnusedAttributes(); - - _gl.drawArrays( _gl.TRIANGLES, 0, object.count ); - - object.count = 0; - - }; - - function setupVertexAttributes( material, programAttributes, geometryAttributes, startIndex ) { - - for ( var attributeName in programAttributes ) { - - var attributePointer = programAttributes[ attributeName ]; - var attributeItem = geometryAttributes[ attributeName ]; - - if ( attributePointer >= 0 ) { - - if ( attributeItem ) { - - var attributeSize = attributeItem.itemSize; - - _gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer ); - enableAttribute( attributePointer ); - _gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, startIndex * attributeSize * 4 ); // 4 bytes per Float32 - - } else if ( material.defaultAttributeValues ) { - - if ( material.defaultAttributeValues[ attributeName ].length === 2 ) { - - _gl.vertexAttrib2fv( attributePointer, material.defaultAttributeValues[ attributeName ] ); - - } else if ( material.defaultAttributeValues[ attributeName ].length === 3 ) { - - _gl.vertexAttrib3fv( attributePointer, material.defaultAttributeValues[ attributeName ] ); - - } - - } - - } - - } - - disableUnusedAttributes(); - - } - - this.renderBufferDirect = function ( camera, lights, fog, material, geometry, object ) { - - if ( material.visible === false ) return; - - var linewidth, a, attribute; - var attributeItem, attributeName, attributePointer, attributeSize; - - var program = setProgram( camera, lights, fog, material, object ); - - var programAttributes = program.attributes; - var geometryAttributes = geometry.attributes; - - var updateBuffers = false, - wireframeBit = material.wireframe ? 1 : 0, - geometryHash = ( geometry.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit; - - if ( geometryHash !== _currentGeometryGroupHash ) { - - _currentGeometryGroupHash = geometryHash; - updateBuffers = true; - - } - - if ( updateBuffers ) { - - initAttributes(); - - } - - // render mesh - - if ( object instanceof THREE.Mesh ) { - - var index = geometryAttributes[ "index" ]; - - if ( index ) { - - // indexed triangles - - var type, size; - - if ( index.array instanceof Uint32Array ) { - - type = _gl.UNSIGNED_INT; - size = 4; - - } else { - - type = _gl.UNSIGNED_SHORT; - size = 2; - - } - - var offsets = geometry.offsets; - - if ( offsets.length === 0 ) { - - if ( updateBuffers ) { - - setupVertexAttributes( material, programAttributes, geometryAttributes, 0 ); - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer ); - - } - - _gl.drawElements( _gl.TRIANGLES, index.array.length, type, 0 ); - - _this.info.render.calls ++; - _this.info.render.vertices += index.array.length; // not really true, here vertices can be shared - _this.info.render.faces += index.array.length / 3; - - } else { - - // if there is more than 1 chunk - // must set attribute pointers to use new offsets for each chunk - // even if geometry and materials didn't change - - updateBuffers = true; - - for ( var i = 0, il = offsets.length; i < il; i ++ ) { - - var startIndex = offsets[ i ].index; - - if ( updateBuffers ) { - - setupVertexAttributes( material, programAttributes, geometryAttributes, startIndex ); - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer ); - - } - - // render indexed triangles - - _gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, type, offsets[ i ].start * size ); - - _this.info.render.calls ++; - _this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared - _this.info.render.faces += offsets[ i ].count / 3; - - } - - } - - } else { - - // non-indexed triangles - - if ( updateBuffers ) { - - setupVertexAttributes( material, programAttributes, geometryAttributes, 0 ); - - } - - var position = geometry.attributes[ "position" ]; - - // render non-indexed triangles - - _gl.drawArrays( _gl.TRIANGLES, 0, position.array.length / 3 ); - - _this.info.render.calls ++; - _this.info.render.vertices += position.array.length / 3; - _this.info.render.faces += position.array.length / 9; - - } - - } else if ( object instanceof THREE.ParticleSystem ) { - - // render particles - - if ( updateBuffers ) { - - setupVertexAttributes( material, programAttributes, geometryAttributes, 0 ); - - } - - var position = geometryAttributes[ "position" ]; - - // render particles - - _gl.drawArrays( _gl.POINTS, 0, position.array.length / 3 ); - - _this.info.render.calls ++; - _this.info.render.points += position.array.length / 3; - - } else if ( object instanceof THREE.Line ) { - - var mode = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES; - - setLineWidth( material.linewidth ); - - var index = geometryAttributes[ "index" ]; - - if ( index ) { - - // indexed lines - - var type, size; - - if ( index.array instanceof Uint32Array ){ - - type = _gl.UNSIGNED_INT; - size = 4; - - } else { - - type = _gl.UNSIGNED_SHORT; - size = 2; - - } - - var offsets = geometry.offsets; - - if ( offsets.length === 0 ) { - - if ( updateBuffers ) { - - setupVertexAttributes( material, programAttributes, geometryAttributes, 0 ); - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer ); - - } - - _gl.drawElements( _gl.LINES, index.array.length, type, 0 ); // 2 bytes per Uint16Array - - _this.info.render.calls ++; - _this.info.render.vertices += index.array.length; // not really true, here vertices can be shared - - } else { - - // if there is more than 1 chunk - // must set attribute pointers to use new offsets for each chunk - // even if geometry and materials didn't change - - if ( offsets.length > 1 ) updateBuffers = true; - - for ( var i = 0, il = offsets.length; i < il; i ++ ) { - - var startIndex = offsets[ i ].index; - - if ( updateBuffers ) { - - setupVertexAttributes( material, programAttributes, geometryAttributes, startIndex ); - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer ); - - } - - // render indexed lines - - _gl.drawElements( _gl.LINES, offsets[ i ].count, type, offsets[ i ].start * size ); // 2 bytes per Uint16Array - - _this.info.render.calls ++; - _this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared - - } - - } - - } else { - - // non-indexed lines - - if ( updateBuffers ) { - - setupVertexAttributes( material, programAttributes, geometryAttributes, 0 ); - - } - - var position = geometryAttributes[ "position" ]; - - _gl.drawArrays( mode, 0, position.array.length / 3 ); - - _this.info.render.calls ++; - _this.info.render.points += position.array.length / 3; - - } - - } - - }; - - this.renderBuffer = function ( camera, lights, fog, material, geometryGroup, object ) { - - if ( material.visible === false ) return; - - var linewidth, a, attribute, i, il; - - var program = setProgram( camera, lights, fog, material, object ); - - var attributes = program.attributes; - - var updateBuffers = false, - wireframeBit = material.wireframe ? 1 : 0, - geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit; - - if ( geometryGroupHash !== _currentGeometryGroupHash ) { - - _currentGeometryGroupHash = geometryGroupHash; - updateBuffers = true; - - } - - if ( updateBuffers ) { - - initAttributes(); - - } - - // vertices - - if ( !material.morphTargets && attributes.position >= 0 ) { - - if ( updateBuffers ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer ); - enableAttribute( attributes.position ); - _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 ); - - } - - } else { - - if ( object.morphTargetBase ) { - - setupMorphTargets( material, geometryGroup, object ); - - } - - } - - - if ( updateBuffers ) { - - // custom attributes - - // Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers - - if ( geometryGroup.__webglCustomAttributesList ) { - - for ( i = 0, il = geometryGroup.__webglCustomAttributesList.length; i < il; i ++ ) { - - attribute = geometryGroup.__webglCustomAttributesList[ i ]; - - if ( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer ); - enableAttribute( attributes[ attribute.buffer.belongsToAttribute ] ); - _gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 ); - - } - - } - - } - - - // colors - - if ( attributes.color >= 0 ) { - - if ( object.geometry.colors.length > 0 || object.geometry.faces.length > 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer ); - enableAttribute( attributes.color ); - _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 ); - - } else if ( material.defaultAttributeValues ) { - - - _gl.vertexAttrib3fv( attributes.color, material.defaultAttributeValues.color ); - - } - - } - - // normals - - if ( attributes.normal >= 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer ); - enableAttribute( attributes.normal ); - _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 ); - - } - - // tangents - - if ( attributes.tangent >= 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer ); - enableAttribute( attributes.tangent ); - _gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 ); - - } - - // uvs - - if ( attributes.uv >= 0 ) { - - if ( object.geometry.faceVertexUvs[0] ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer ); - enableAttribute( attributes.uv ); - _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 ); - - } else if ( material.defaultAttributeValues ) { - - - _gl.vertexAttrib2fv( attributes.uv, material.defaultAttributeValues.uv ); - - } - - } - - if ( attributes.uv2 >= 0 ) { - - if ( object.geometry.faceVertexUvs[1] ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer ); - enableAttribute( attributes.uv2 ); - _gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 ); - - } else if ( material.defaultAttributeValues ) { - - - _gl.vertexAttrib2fv( attributes.uv2, material.defaultAttributeValues.uv2 ); - - } - - } - - if ( material.skinning && - attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer ); - enableAttribute( attributes.skinIndex ); - _gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 ); - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer ); - enableAttribute( attributes.skinWeight ); - _gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 ); - - } - - // line distances - - if ( attributes.lineDistance >= 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglLineDistanceBuffer ); - enableAttribute( attributes.lineDistance ); - _gl.vertexAttribPointer( attributes.lineDistance, 1, _gl.FLOAT, false, 0, 0 ); - - } - - } - - disableUnusedAttributes(); - - // render mesh - - if ( object instanceof THREE.Mesh ) { - - var type = geometryGroup.__typeArray === Uint32Array ? _gl.UNSIGNED_INT : _gl.UNSIGNED_SHORT; - - // wireframe - - if ( material.wireframe ) { - - setLineWidth( material.wireframeLinewidth ); - if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer ); - _gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, type, 0 ); - - // triangles - - } else { - - if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer ); - _gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, type, 0 ); - - } - - _this.info.render.calls ++; - _this.info.render.vertices += geometryGroup.__webglFaceCount; - _this.info.render.faces += geometryGroup.__webglFaceCount / 3; - - // render lines - - } else if ( object instanceof THREE.Line ) { - - var mode = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES; - - setLineWidth( material.linewidth ); - - _gl.drawArrays( mode, 0, geometryGroup.__webglLineCount ); - - _this.info.render.calls ++; - - // render particles - - } else if ( object instanceof THREE.ParticleSystem ) { - - _gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount ); - - _this.info.render.calls ++; - _this.info.render.points += geometryGroup.__webglParticleCount; - - } - - }; - - function initAttributes() { - - for ( var i = 0, l = _newAttributes.length; i < l; i ++ ) { - - _newAttributes[ i ] = 0; - - } - - } - - function enableAttribute( attribute ) { - - _newAttributes[ attribute ] = 1; - - if ( _enabledAttributes[ attribute ] === 0 ) { - - _gl.enableVertexAttribArray( attribute ); - _enabledAttributes[ attribute ] = 1; - - } - - } - - function disableUnusedAttributes() { - - for ( var i = 0, l = _enabledAttributes.length; i < l; i ++ ) { - - if ( _enabledAttributes[ i ] !== _newAttributes[ i ] ) { - - _gl.disableVertexAttribArray( i ); - _enabledAttributes[ i ] = 0; - - } - - } - - } - - function setupMorphTargets ( material, geometryGroup, object ) { - - // set base - - var attributes = material.program.attributes; - - if ( object.morphTargetBase !== -1 && attributes.position >= 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] ); - enableAttribute( attributes.position ); - _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 ); - - } else if ( attributes.position >= 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer ); - enableAttribute( attributes.position ); - _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 ); - - } - - if ( object.morphTargetForcedOrder.length ) { - - // set forced order - - var m = 0; - var order = object.morphTargetForcedOrder; - var influences = object.morphTargetInfluences; - - while ( m < material.numSupportedMorphTargets && m < order.length ) { - - if ( attributes[ "morphTarget" + m ] >= 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] ); - enableAttribute( attributes[ "morphTarget" + m ] ); - _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 ); - - } - - if ( attributes[ "morphNormal" + m ] >= 0 && material.morphNormals ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ order[ m ] ] ); - enableAttribute( attributes[ "morphNormal" + m ] ); - _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 ); - - } - - object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ]; - - m ++; - } - - } else { - - // find the most influencing - - var influence, activeInfluenceIndices = []; - var influences = object.morphTargetInfluences; - var i, il = influences.length; - - for ( i = 0; i < il; i ++ ) { - - influence = influences[ i ]; - - if ( influence > 0 ) { - - activeInfluenceIndices.push( [ influence, i ] ); - - } - - } - - if ( activeInfluenceIndices.length > material.numSupportedMorphTargets ) { - - activeInfluenceIndices.sort( numericalSort ); - activeInfluenceIndices.length = material.numSupportedMorphTargets; - - } else if ( activeInfluenceIndices.length > material.numSupportedMorphNormals ) { - - activeInfluenceIndices.sort( numericalSort ); - - } else if ( activeInfluenceIndices.length === 0 ) { - - activeInfluenceIndices.push( [ 0, 0 ] ); - - }; - - var influenceIndex, m = 0; - - while ( m < material.numSupportedMorphTargets ) { - - if ( activeInfluenceIndices[ m ] ) { - - influenceIndex = activeInfluenceIndices[ m ][ 1 ]; - - if ( attributes[ "morphTarget" + m ] >= 0 ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] ); - enableAttribute( attributes[ "morphTarget" + m ] ); - _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 ); - - } - - if ( attributes[ "morphNormal" + m ] >= 0 && material.morphNormals ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ influenceIndex ] ); - enableAttribute( attributes[ "morphNormal" + m ] ); - _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 ); - - - } - - object.__webglMorphTargetInfluences[ m ] = influences[ influenceIndex ]; - - } else { - - /* - _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 ); - - if ( material.morphNormals ) { - - _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 ); - - } - */ - - object.__webglMorphTargetInfluences[ m ] = 0; - - } - - m ++; - - } - - } - - // load updated influences uniform - - if ( material.program.uniforms.morphTargetInfluences !== null ) { - - _gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences ); - - } - - }; - - // Sorting - - function painterSortStable ( a, b ) { - - if ( a.z !== b.z ) { - - return b.z - a.z; - - } else { - - return a.id - b.id; - - } - - }; - - function numericalSort ( a, b ) { - - return b[ 0 ] - a[ 0 ]; - - }; - - - // Rendering - - this.render = function ( scene, camera, renderTarget, forceClear ) { - - if ( camera instanceof THREE.Camera === false ) { - - console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' ); - return; - - } - - var i, il, - - webglObject, object, - renderList, - - lights = scene.__lights, - fog = scene.fog; - - // reset caching for this frame - - _currentMaterialId = -1; - _lightsNeedUpdate = true; - - // update scene graph - - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - - // update camera matrices and frustum - - if ( camera.parent === undefined ) camera.updateMatrixWorld(); - - camera.matrixWorldInverse.getInverse( camera.matrixWorld ); - - _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); - _frustum.setFromMatrix( _projScreenMatrix ); - - // update WebGL objects - - if ( this.autoUpdateObjects ) this.initWebGLObjects( scene ); - - // custom render plugins (pre pass) - - renderPlugins( this.renderPluginsPre, scene, camera ); - - // - - _this.info.render.calls = 0; - _this.info.render.vertices = 0; - _this.info.render.faces = 0; - _this.info.render.points = 0; - - this.setRenderTarget( renderTarget ); - - if ( this.autoClear || forceClear ) { - - this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil ); - - } - - // set matrices for regular objects (frustum culled) - - renderList = scene.__webglObjects; - - for ( i = 0, il = renderList.length; i < il; i ++ ) { - - webglObject = renderList[ i ]; - object = webglObject.object; - - webglObject.id = i; - webglObject.render = false; - - if ( object.visible ) { - - if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.intersectsObject( object ) ) { - - setupMatrices( object, camera ); - - unrollBufferMaterial( webglObject ); - - webglObject.render = true; - - if ( this.sortObjects === true ) { - - if ( object.renderDepth !== null ) { - - webglObject.z = object.renderDepth; - - } else { - - _vector3.setFromMatrixPosition( object.matrixWorld ); - _vector3.applyProjection( _projScreenMatrix ); - - webglObject.z = _vector3.z; - - } - - } - - } - - } - - } - - if ( this.sortObjects ) { - - renderList.sort( painterSortStable ); - - } - - // set matrices for immediate objects - - renderList = scene.__webglObjectsImmediate; - - for ( i = 0, il = renderList.length; i < il; i ++ ) { - - webglObject = renderList[ i ]; - object = webglObject.object; - - if ( object.visible ) { - - setupMatrices( object, camera ); - - unrollImmediateBufferMaterial( webglObject ); - - } - - } - - if ( scene.overrideMaterial ) { - - var material = scene.overrideMaterial; - - this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst ); - this.setDepthTest( material.depthTest ); - this.setDepthWrite( material.depthWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); - - renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material ); - renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material ); - - } else { - - var material = null; - - // opaque pass (front-to-back order) - - this.setBlending( THREE.NoBlending ); - - renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false, material ); - renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false, material ); - - // transparent pass (back-to-front order) - - renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true, material ); - renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true, material ); - - } - - // custom render plugins (post pass) - - renderPlugins( this.renderPluginsPost, scene, camera ); - - - // Generate mipmap if we're using any kind of mipmap filtering - - if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) { - - updateRenderTargetMipmap( renderTarget ); - - } - - // Ensure depth buffer writing is enabled so it can be cleared on next render - - this.setDepthTest( true ); - this.setDepthWrite( true ); - - // _gl.finish(); - - }; - - function renderPlugins( plugins, scene, camera ) { - - if ( ! plugins.length ) return; - - for ( var i = 0, il = plugins.length; i < il; i ++ ) { - - // reset state for plugin (to start from clean slate) - - _currentProgram = null; - _currentCamera = null; - - _oldBlending = -1; - _oldDepthTest = -1; - _oldDepthWrite = -1; - _oldDoubleSided = -1; - _oldFlipSided = -1; - _currentGeometryGroupHash = -1; - _currentMaterialId = -1; - - _lightsNeedUpdate = true; - - plugins[ i ].render( scene, camera, _currentWidth, _currentHeight ); - - // reset state after plugin (anything could have changed) - - _currentProgram = null; - _currentCamera = null; - - _oldBlending = -1; - _oldDepthTest = -1; - _oldDepthWrite = -1; - _oldDoubleSided = -1; - _oldFlipSided = -1; - _currentGeometryGroupHash = -1; - _currentMaterialId = -1; - - _lightsNeedUpdate = true; - - } - - }; - - function renderObjects( renderList, reverse, materialType, camera, lights, fog, useBlending, overrideMaterial ) { - - var webglObject, object, buffer, material, start, end, delta; - - if ( reverse ) { - - start = renderList.length - 1; - end = -1; - delta = -1; - - } else { - - start = 0; - end = renderList.length; - delta = 1; - } - - for ( var i = start; i !== end; i += delta ) { - - webglObject = renderList[ i ]; - - if ( webglObject.render ) { - - object = webglObject.object; - buffer = webglObject.buffer; - - if ( overrideMaterial ) { - - material = overrideMaterial; - - } else { - - material = webglObject[ materialType ]; - - if ( ! material ) continue; - - if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst ); - - _this.setDepthTest( material.depthTest ); - _this.setDepthWrite( material.depthWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); - - } - - _this.setMaterialFaces( material ); - - if ( buffer instanceof THREE.BufferGeometry ) { - - _this.renderBufferDirect( camera, lights, fog, material, buffer, object ); - - } else { - - _this.renderBuffer( camera, lights, fog, material, buffer, object ); - - } - - } - - } - - }; - - function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, useBlending, overrideMaterial ) { - - var webglObject, object, material, program; - - for ( var i = 0, il = renderList.length; i < il; i ++ ) { - - webglObject = renderList[ i ]; - object = webglObject.object; - - if ( object.visible ) { - - if ( overrideMaterial ) { - - material = overrideMaterial; - - } else { - - material = webglObject[ materialType ]; - - if ( ! material ) continue; - - if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst ); - - _this.setDepthTest( material.depthTest ); - _this.setDepthWrite( material.depthWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); - - } - - _this.renderImmediateObject( camera, lights, fog, material, object ); - - } - - } - - }; - - this.renderImmediateObject = function ( camera, lights, fog, material, object ) { - - var program = setProgram( camera, lights, fog, material, object ); - - _currentGeometryGroupHash = -1; - - _this.setMaterialFaces( material ); - - if ( object.immediateRenderCallback ) { - - object.immediateRenderCallback( program, _gl, _frustum ); - - } else { - - object.render( function( object ) { _this.renderBufferImmediate( object, program, material ); } ); - - } - - }; - - function unrollImmediateBufferMaterial ( globject ) { - - var object = globject.object, - material = object.material; - - if ( material.transparent ) { - - globject.transparent = material; - globject.opaque = null; - - } else { - - globject.opaque = material; - globject.transparent = null; - - } - - }; - - function unrollBufferMaterial ( globject ) { - - var object = globject.object; - var buffer = globject.buffer; - - var geometry = object.geometry; - var material = object.material; - - if ( material instanceof THREE.MeshFaceMaterial ) { - - var materialIndex = geometry instanceof THREE.BufferGeometry ? 0 : buffer.materialIndex; - - material = material.materials[ materialIndex ]; - - if ( material.transparent ) { - - globject.transparent = material; - globject.opaque = null; - - } else { - - globject.opaque = material; - globject.transparent = null; - - } - - } else { - - if ( material ) { - - if ( material.transparent ) { - - globject.transparent = material; - globject.opaque = null; - - } else { - - globject.opaque = material; - globject.transparent = null; - - } - - } - - } - - }; - - // Objects refresh - - this.initWebGLObjects = function ( scene ) { - - if ( !scene.__webglObjects ) { - - scene.__webglObjects = []; - scene.__webglObjectsImmediate = []; - scene.__webglSprites = []; - scene.__webglFlares = []; - - } - - while ( scene.__objectsAdded.length ) { - - addObject( scene.__objectsAdded[ 0 ], scene ); - scene.__objectsAdded.splice( 0, 1 ); - - } - - while ( scene.__objectsRemoved.length ) { - - removeObject( scene.__objectsRemoved[ 0 ], scene ); - scene.__objectsRemoved.splice( 0, 1 ); - - } - - // update must be called after objects adding / removal - - for ( var o = 0, ol = scene.__webglObjects.length; o < ol; o ++ ) { - - var object = scene.__webglObjects[ o ].object; - - // TODO: Remove this hack (WebGLRenderer refactoring) - - if ( object.__webglInit === undefined ) { - - if ( object.__webglActive !== undefined ) { - - removeObject( object, scene ); - - } - - addObject( object, scene ); - - } - - updateObject( object ); - - } - - }; - - // Objects adding - - function addObject( object, scene ) { - - var g, geometry, material, geometryGroup; - - if ( object.__webglInit === undefined ) { - - object.__webglInit = true; - - object._modelViewMatrix = new THREE.Matrix4(); - object._normalMatrix = new THREE.Matrix3(); - - geometry = object.geometry; - - if ( geometry === undefined ) { - - // ImmediateRenderObject - - } else if ( geometry.__webglInit === undefined ) { - - geometry.__webglInit = true; - geometry.addEventListener( 'dispose', onGeometryDispose ); - - if ( geometry instanceof THREE.BufferGeometry ) { - - initDirectBuffers( geometry ); - - } else if ( object instanceof THREE.Mesh ) { - - material = object.material; - - if ( geometry.geometryGroups === undefined ) { - - geometry.makeGroups( material instanceof THREE.MeshFaceMaterial, _glExtensionElementIndexUint ? 4294967296 : 65535 ); - - } - - // create separate VBOs per geometry chunk - - for ( g in geometry.geometryGroups ) { - - geometryGroup = geometry.geometryGroups[ g ]; - - // initialise VBO on the first access - - if ( ! geometryGroup.__webglVertexBuffer ) { - - createMeshBuffers( geometryGroup ); - initMeshBuffers( geometryGroup, object ); - - geometry.verticesNeedUpdate = true; - geometry.morphTargetsNeedUpdate = true; - geometry.elementsNeedUpdate = true; - geometry.uvsNeedUpdate = true; - geometry.normalsNeedUpdate = true; - geometry.tangentsNeedUpdate = true; - geometry.colorsNeedUpdate = true; - - } - - } - - } else if ( object instanceof THREE.Line ) { - - if ( ! geometry.__webglVertexBuffer ) { - - createLineBuffers( geometry ); - initLineBuffers( geometry, object ); - - geometry.verticesNeedUpdate = true; - geometry.colorsNeedUpdate = true; - geometry.lineDistancesNeedUpdate = true; - - } - - } else if ( object instanceof THREE.ParticleSystem ) { - - if ( ! geometry.__webglVertexBuffer ) { - - createParticleBuffers( geometry ); - initParticleBuffers( geometry, object ); - - geometry.verticesNeedUpdate = true; - geometry.colorsNeedUpdate = true; - - } - - } - - } - - } - - if ( object.__webglActive === undefined ) { - - if ( object instanceof THREE.Mesh ) { - - geometry = object.geometry; - - if ( geometry instanceof THREE.BufferGeometry ) { - - addBuffer( scene.__webglObjects, geometry, object ); - - } else if ( geometry instanceof THREE.Geometry ) { - - for ( g in geometry.geometryGroups ) { - - geometryGroup = geometry.geometryGroups[ g ]; - - addBuffer( scene.__webglObjects, geometryGroup, object ); - - } - - } - - } else if ( object instanceof THREE.Line || - object instanceof THREE.ParticleSystem ) { - - geometry = object.geometry; - addBuffer( scene.__webglObjects, geometry, object ); - - } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) { - - addBufferImmediate( scene.__webglObjectsImmediate, object ); - - } else if ( object instanceof THREE.Sprite ) { - - scene.__webglSprites.push( object ); - - } else if ( object instanceof THREE.LensFlare ) { - - scene.__webglFlares.push( object ); - - } - - object.__webglActive = true; - - } - - }; - - function addBuffer( objlist, buffer, object ) { - - objlist.push( - { - id: null, - buffer: buffer, - object: object, - opaque: null, - transparent: null, - z: 0 - } - ); - - }; - - function addBufferImmediate( objlist, object ) { - - objlist.push( - { - id: null, - object: object, - opaque: null, - transparent: null, - z: 0 - } - ); - - }; - - // Objects updates - - function updateObject( object ) { - - var geometry = object.geometry, - geometryGroup, customAttributesDirty, material; - - if ( geometry instanceof THREE.BufferGeometry ) { - - setDirectBuffers( geometry, _gl.DYNAMIC_DRAW ); - - } else if ( object instanceof THREE.Mesh ) { - - // check all geometry groups - - for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) { - - geometryGroup = geometry.geometryGroupsList[ i ]; - - material = getBufferMaterial( object, geometryGroup ); - - if ( geometry.buffersNeedUpdate ) { - - initMeshBuffers( geometryGroup, object ); - - } - - customAttributesDirty = material.attributes && areCustomAttributesDirty( material ); - - if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate || - geometry.uvsNeedUpdate || geometry.normalsNeedUpdate || - geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) { - - setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, !geometry.dynamic, material ); - - } - - } - - geometry.verticesNeedUpdate = false; - geometry.morphTargetsNeedUpdate = false; - geometry.elementsNeedUpdate = false; - geometry.uvsNeedUpdate = false; - geometry.normalsNeedUpdate = false; - geometry.colorsNeedUpdate = false; - geometry.tangentsNeedUpdate = false; - - geometry.buffersNeedUpdate = false; - - material.attributes && clearCustomAttributes( material ); - - } else if ( object instanceof THREE.Line ) { - - material = getBufferMaterial( object, geometry ); - - customAttributesDirty = material.attributes && areCustomAttributesDirty( material ); - - if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || geometry.lineDistancesNeedUpdate || customAttributesDirty ) { - - setLineBuffers( geometry, _gl.DYNAMIC_DRAW ); - - } - - geometry.verticesNeedUpdate = false; - geometry.colorsNeedUpdate = false; - geometry.lineDistancesNeedUpdate = false; - - material.attributes && clearCustomAttributes( material ); - - - } else if ( object instanceof THREE.ParticleSystem ) { - - material = getBufferMaterial( object, geometry ); - - customAttributesDirty = material.attributes && areCustomAttributesDirty( material ); - - if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) { - - setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object ); - - } - - geometry.verticesNeedUpdate = false; - geometry.colorsNeedUpdate = false; - - material.attributes && clearCustomAttributes( material ); - - } - - }; - - // Objects updates - custom attributes check - - function areCustomAttributesDirty( material ) { - - for ( var a in material.attributes ) { - - if ( material.attributes[ a ].needsUpdate ) return true; - - } - - return false; - - }; - - function clearCustomAttributes( material ) { - - for ( var a in material.attributes ) { - - material.attributes[ a ].needsUpdate = false; - - } - - }; - - // Objects removal - - function removeObject( object, scene ) { - - if ( object instanceof THREE.Mesh || - object instanceof THREE.ParticleSystem || - object instanceof THREE.Line ) { - - removeInstances( scene.__webglObjects, object ); - - } else if ( object instanceof THREE.Sprite ) { - - removeInstancesDirect( scene.__webglSprites, object ); - - } else if ( object instanceof THREE.LensFlare ) { - - removeInstancesDirect( scene.__webglFlares, object ); - - } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) { - - removeInstances( scene.__webglObjectsImmediate, object ); - - } - - delete object.__webglActive; - - }; - - function removeInstances( objlist, object ) { - - for ( var o = objlist.length - 1; o >= 0; o -- ) { - - if ( objlist[ o ].object === object ) { - - objlist.splice( o, 1 ); - - } - - } - - }; - - function removeInstancesDirect( objlist, object ) { - - for ( var o = objlist.length - 1; o >= 0; o -- ) { - - if ( objlist[ o ] === object ) { - - objlist.splice( o, 1 ); - - } - - } - - }; - - // Materials - - this.initMaterial = function ( material, lights, fog, object ) { - - material.addEventListener( 'dispose', onMaterialDispose ); - - var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID; - - if ( material instanceof THREE.MeshDepthMaterial ) { - - shaderID = 'depth'; - - } else if ( material instanceof THREE.MeshNormalMaterial ) { - - shaderID = 'normal'; - - } else if ( material instanceof THREE.MeshBasicMaterial ) { - - shaderID = 'basic'; - - } else if ( material instanceof THREE.MeshLambertMaterial ) { - - shaderID = 'lambert'; - - } else if ( material instanceof THREE.MeshPhongMaterial ) { - - shaderID = 'phong'; - - } else if ( material instanceof THREE.LineBasicMaterial ) { - - shaderID = 'basic'; - - } else if ( material instanceof THREE.LineDashedMaterial ) { - - shaderID = 'dashed'; - - } else if ( material instanceof THREE.ParticleSystemMaterial ) { - - shaderID = 'particle_basic'; - - } - - if ( shaderID ) { - - setMaterialShaders( material, THREE.ShaderLib[ shaderID ] ); - - } - - // heuristics to create shader parameters according to lights in the scene - // (not to blow over maxLights budget) - - maxLightCount = allocateLights( lights ); - - maxShadows = allocateShadows( lights ); - - maxBones = allocateBones( object ); - - parameters = { - - precision: _precision, - supportsVertexTextures: _supportsVertexTextures, - - map: !!material.map, - envMap: !!material.envMap, - lightMap: !!material.lightMap, - bumpMap: !!material.bumpMap, - normalMap: !!material.normalMap, - specularMap: !!material.specularMap, - - vertexColors: material.vertexColors, - - fog: fog, - useFog: material.fog, - fogExp: fog instanceof THREE.FogExp2, - - sizeAttenuation: material.sizeAttenuation, - logarithmicDepthBuffer: _logarithmicDepthBuffer, - - skinning: material.skinning, - maxBones: maxBones, - useVertexTexture: _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture, - - morphTargets: material.morphTargets, - morphNormals: material.morphNormals, - maxMorphTargets: this.maxMorphTargets, - maxMorphNormals: this.maxMorphNormals, - - maxDirLights: maxLightCount.directional, - maxPointLights: maxLightCount.point, - maxSpotLights: maxLightCount.spot, - maxHemiLights: maxLightCount.hemi, - - maxShadows: maxShadows, - shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow && maxShadows > 0, - shadowMapType: this.shadowMapType, - shadowMapDebug: this.shadowMapDebug, - shadowMapCascade: this.shadowMapCascade, - - alphaTest: material.alphaTest, - metal: material.metal, - wrapAround: material.wrapAround, - doubleSided: material.side === THREE.DoubleSide, - flipSided: material.side === THREE.BackSide - - }; - - // Generate code - - var chunks = []; - - if ( shaderID ) { - - chunks.push( shaderID ); - - } else { - - chunks.push( material.fragmentShader ); - chunks.push( material.vertexShader ); - - } - - for ( var d in material.defines ) { - - chunks.push( d ); - chunks.push( material.defines[ d ] ); - - } - - for ( var p in parameters ) { - - chunks.push( p ); - chunks.push( parameters[ p ] ); - - } - - var code = chunks.join(); - - var program; - - // Check if code has been already compiled - - for ( var p = 0, pl = _programs.length; p < pl; p ++ ) { - - var programInfo = _programs[ p ]; - - if ( programInfo.code === code ) { - - program = programInfo; - program.usedTimes ++; - - break; - - } - - } - - if ( program === undefined ) { - - program = new THREE.WebGLProgram( this, code, material, parameters ); - _programs.push( program ); - - _this.info.memory.programs = _programs.length; - - } - - material.program = program; - - var attributes = material.program.attributes; - - if ( material.morphTargets ) { - - material.numSupportedMorphTargets = 0; - - var id, base = "morphTarget"; - - for ( i = 0; i < this.maxMorphTargets; i ++ ) { - - id = base + i; - - if ( attributes[ id ] >= 0 ) { - - material.numSupportedMorphTargets ++; - - } - - } - - } - - if ( material.morphNormals ) { - - material.numSupportedMorphNormals = 0; - - var id, base = "morphNormal"; - - for ( i = 0; i < this.maxMorphNormals; i ++ ) { - - id = base + i; - - if ( attributes[ id ] >= 0 ) { - - material.numSupportedMorphNormals ++; - - } - - } - - } - - material.uniformsList = []; - - for ( u in material.uniforms ) { - - material.uniformsList.push( [ material.uniforms[ u ], u ] ); - - } - - }; - - function setMaterialShaders( material, shaders ) { - - material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms ); - material.vertexShader = shaders.vertexShader; - material.fragmentShader = shaders.fragmentShader; - - }; - - function setProgram( camera, lights, fog, material, object ) { - - _usedTextureUnits = 0; - - if ( material.needsUpdate ) { - - if ( material.program ) deallocateMaterial( material ); - - _this.initMaterial( material, lights, fog, object ); - material.needsUpdate = false; - - } - - if ( material.morphTargets ) { - - if ( ! object.__webglMorphTargetInfluences ) { - - object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets ); - - } - - } - - var refreshMaterial = false; - - var program = material.program, - p_uniforms = program.uniforms, - m_uniforms = material.uniforms; - - if ( program.id !== _currentProgram ) { - - _gl.useProgram( program.program ); - _currentProgram = program.id; - - refreshMaterial = true; - - } - - if ( material.id !== _currentMaterialId ) { - - _currentMaterialId = material.id; - refreshMaterial = true; - - } - - if ( refreshMaterial || camera !== _currentCamera ) { - - _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements ); - - if ( _logarithmicDepthBuffer ) { - - _gl.uniform1f(p_uniforms.logDepthBufFC, 2.0 / (Math.log(camera.far + 1.0) / Math.LN2)); - - } - - - if ( camera !== _currentCamera ) _currentCamera = camera; - - } - - // skinning uniforms must be set even if material didn't change - // auto-setting of texture unit for bone texture must go before other textures - // not sure why, but otherwise weird things happen - - if ( material.skinning ) { - - if ( _supportsBoneTextures && object.skeleton.useVertexTexture ) { - - if ( p_uniforms.boneTexture !== null ) { - - var textureUnit = getTextureUnit(); - - _gl.uniform1i( p_uniforms.boneTexture, textureUnit ); - _this.setTexture( object.skeleton.boneTexture, textureUnit ); - - } - - if ( p_uniforms.boneTextureWidth !== null ) { - - _gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth ); - - } - - if ( p_uniforms.boneTextureHeight !== null ) { - - _gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight ); - - } - - } else { - - if ( p_uniforms.boneGlobalMatrices !== null ) { - - _gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices ); - - } - - } - - } - - if ( refreshMaterial ) { - - // refresh uniforms common to several materials - - if ( fog && material.fog ) { - - refreshUniformsFog( m_uniforms, fog ); - - } - - if ( material instanceof THREE.MeshPhongMaterial || - material instanceof THREE.MeshLambertMaterial || - material.lights ) { - - if ( _lightsNeedUpdate ) { - - setupLights( program, lights ); - _lightsNeedUpdate = false; - - } - - refreshUniformsLights( m_uniforms, _lights ); - - } - - if ( material instanceof THREE.MeshBasicMaterial || - material instanceof THREE.MeshLambertMaterial || - material instanceof THREE.MeshPhongMaterial ) { - - refreshUniformsCommon( m_uniforms, material ); - - } - - // refresh single material specific uniforms - - if ( material instanceof THREE.LineBasicMaterial ) { - - refreshUniformsLine( m_uniforms, material ); - - } else if ( material instanceof THREE.LineDashedMaterial ) { - - refreshUniformsLine( m_uniforms, material ); - refreshUniformsDash( m_uniforms, material ); - - } else if ( material instanceof THREE.ParticleSystemMaterial ) { - - refreshUniformsParticle( m_uniforms, material ); - - } else if ( material instanceof THREE.MeshPhongMaterial ) { - - refreshUniformsPhong( m_uniforms, material ); - - } else if ( material instanceof THREE.MeshLambertMaterial ) { - - refreshUniformsLambert( m_uniforms, material ); - - } else if ( material instanceof THREE.MeshDepthMaterial ) { - - m_uniforms.mNear.value = camera.near; - m_uniforms.mFar.value = camera.far; - m_uniforms.opacity.value = material.opacity; - - } else if ( material instanceof THREE.MeshNormalMaterial ) { - - m_uniforms.opacity.value = material.opacity; - - } - - if ( object.receiveShadow && ! material._shadowPass ) { - - refreshUniformsShadow( m_uniforms, lights ); - - } - - // load common uniforms - - loadUniformsGeneric( program, material.uniformsList ); - - // load material specific uniforms - // (shader material also gets them for the sake of genericity) - - if ( material instanceof THREE.ShaderMaterial || - material instanceof THREE.MeshPhongMaterial || - material.envMap ) { - - if ( p_uniforms.cameraPosition !== null ) { - - _vector3.setFromMatrixPosition( camera.matrixWorld ); - _gl.uniform3f( p_uniforms.cameraPosition, _vector3.x, _vector3.y, _vector3.z ); - - } - - } - - if ( material instanceof THREE.MeshPhongMaterial || - material instanceof THREE.MeshLambertMaterial || - material instanceof THREE.ShaderMaterial || - material.skinning ) { - - if ( p_uniforms.viewMatrix !== null ) { - - _gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera.matrixWorldInverse.elements ); - - } - - } - - } - - loadUniformsMatrices( p_uniforms, object ); - - if ( p_uniforms.modelMatrix !== null ) { - - _gl.uniformMatrix4fv( p_uniforms.modelMatrix, false, object.matrixWorld.elements ); - - } - - return program; - - }; - - // Uniforms (refresh uniforms objects) - - function refreshUniformsCommon ( uniforms, material ) { - - uniforms.opacity.value = material.opacity; - - if ( _this.gammaInput ) { - - uniforms.diffuse.value.copyGammaToLinear( material.color ); - - } else { - - uniforms.diffuse.value = material.color; - - } - - uniforms.map.value = material.map; - uniforms.lightMap.value = material.lightMap; - uniforms.specularMap.value = material.specularMap; - - if ( material.bumpMap ) { - - uniforms.bumpMap.value = material.bumpMap; - uniforms.bumpScale.value = material.bumpScale; - - } - - if ( material.normalMap ) { - - uniforms.normalMap.value = material.normalMap; - uniforms.normalScale.value.copy( material.normalScale ); - - } - - // uv repeat and offset setting priorities - // 1. color map - // 2. specular map - // 3. normal map - // 4. bump map - - var uvScaleMap; - - if ( material.map ) { - - uvScaleMap = material.map; - - } else if ( material.specularMap ) { - - uvScaleMap = material.specularMap; - - } else if ( material.normalMap ) { - - uvScaleMap = material.normalMap; - - } else if ( material.bumpMap ) { - - uvScaleMap = material.bumpMap; - - } - - if ( uvScaleMap !== undefined ) { - - var offset = uvScaleMap.offset; - var repeat = uvScaleMap.repeat; - - uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y ); - - } - - uniforms.envMap.value = material.envMap; - uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1; - - if ( _this.gammaInput ) { - - //uniforms.reflectivity.value = material.reflectivity * material.reflectivity; - uniforms.reflectivity.value = material.reflectivity; - - } else { - - uniforms.reflectivity.value = material.reflectivity; - - } - - uniforms.refractionRatio.value = material.refractionRatio; - uniforms.combine.value = material.combine; - uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping; - - }; - - function refreshUniformsLine ( uniforms, material ) { - - uniforms.diffuse.value = material.color; - uniforms.opacity.value = material.opacity; - - }; - - function refreshUniformsDash ( uniforms, material ) { - - uniforms.dashSize.value = material.dashSize; - uniforms.totalSize.value = material.dashSize + material.gapSize; - uniforms.scale.value = material.scale; - - }; - - function refreshUniformsParticle ( uniforms, material ) { - - uniforms.psColor.value = material.color; - uniforms.opacity.value = material.opacity; - uniforms.size.value = material.size; - uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this. - - uniforms.map.value = material.map; - - }; - - function refreshUniformsFog ( uniforms, fog ) { - - uniforms.fogColor.value = fog.color; - - if ( fog instanceof THREE.Fog ) { - - uniforms.fogNear.value = fog.near; - uniforms.fogFar.value = fog.far; - - } else if ( fog instanceof THREE.FogExp2 ) { - - uniforms.fogDensity.value = fog.density; - - } - - }; - - function refreshUniformsPhong ( uniforms, material ) { - - uniforms.shininess.value = material.shininess; - - if ( _this.gammaInput ) { - - uniforms.ambient.value.copyGammaToLinear( material.ambient ); - uniforms.emissive.value.copyGammaToLinear( material.emissive ); - uniforms.specular.value.copyGammaToLinear( material.specular ); - - } else { - - uniforms.ambient.value = material.ambient; - uniforms.emissive.value = material.emissive; - uniforms.specular.value = material.specular; - - } - - if ( material.wrapAround ) { - - uniforms.wrapRGB.value.copy( material.wrapRGB ); - - } - - }; - - function refreshUniformsLambert ( uniforms, material ) { - - if ( _this.gammaInput ) { - - uniforms.ambient.value.copyGammaToLinear( material.ambient ); - uniforms.emissive.value.copyGammaToLinear( material.emissive ); - - } else { - - uniforms.ambient.value = material.ambient; - uniforms.emissive.value = material.emissive; - - } - - if ( material.wrapAround ) { - - uniforms.wrapRGB.value.copy( material.wrapRGB ); - - } - - }; - - function refreshUniformsLights ( uniforms, lights ) { - - uniforms.ambientLightColor.value = lights.ambient; - - uniforms.directionalLightColor.value = lights.directional.colors; - uniforms.directionalLightDirection.value = lights.directional.positions; - - uniforms.pointLightColor.value = lights.point.colors; - uniforms.pointLightPosition.value = lights.point.positions; - uniforms.pointLightDistance.value = lights.point.distances; - - uniforms.spotLightColor.value = lights.spot.colors; - uniforms.spotLightPosition.value = lights.spot.positions; - uniforms.spotLightDistance.value = lights.spot.distances; - uniforms.spotLightDirection.value = lights.spot.directions; - uniforms.spotLightAngleCos.value = lights.spot.anglesCos; - uniforms.spotLightExponent.value = lights.spot.exponents; - - uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors; - uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors; - uniforms.hemisphereLightDirection.value = lights.hemi.positions; - - }; - - function refreshUniformsShadow ( uniforms, lights ) { - - if ( uniforms.shadowMatrix ) { - - var j = 0; - - for ( var i = 0, il = lights.length; i < il; i ++ ) { - - var light = lights[ i ]; - - if ( ! light.castShadow ) continue; - - if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) { - - uniforms.shadowMap.value[ j ] = light.shadowMap; - uniforms.shadowMapSize.value[ j ] = light.shadowMapSize; - - uniforms.shadowMatrix.value[ j ] = light.shadowMatrix; - - uniforms.shadowDarkness.value[ j ] = light.shadowDarkness; - uniforms.shadowBias.value[ j ] = light.shadowBias; - - j ++; - - } - - } - - } - - }; - - // Uniforms (load to GPU) - - function loadUniformsMatrices ( uniforms, object ) { - - _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrix.elements ); - - if ( uniforms.normalMatrix ) { - - _gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrix.elements ); - - } - - }; - - function getTextureUnit() { - - var textureUnit = _usedTextureUnits; - - if ( textureUnit >= _maxTextures ) { - - console.warn( "WebGLRenderer: trying to use " + textureUnit + " texture units while this GPU supports only " + _maxTextures ); - - } - - _usedTextureUnits += 1; - - return textureUnit; - - }; - - function loadUniformsGeneric ( program, uniforms ) { - - var uniform, value, type, location, texture, textureUnit, i, il, j, jl, offset; - - for ( j = 0, jl = uniforms.length; j < jl; j ++ ) { - - location = program.uniforms[ uniforms[ j ][ 1 ] ]; - if ( !location ) continue; - - uniform = uniforms[ j ][ 0 ]; - - type = uniform.type; - value = uniform.value; - - if ( type === "i" ) { // single integer - - _gl.uniform1i( location, value ); - - } else if ( type === "f" ) { // single float - - _gl.uniform1f( location, value ); - - } else if ( type === "v2" ) { // single THREE.Vector2 - - _gl.uniform2f( location, value.x, value.y ); - - } else if ( type === "v3" ) { // single THREE.Vector3 - - _gl.uniform3f( location, value.x, value.y, value.z ); - - } else if ( type === "v4" ) { // single THREE.Vector4 - - _gl.uniform4f( location, value.x, value.y, value.z, value.w ); - - } else if ( type === "c" ) { // single THREE.Color - - _gl.uniform3f( location, value.r, value.g, value.b ); - - } else if ( type === "iv1" ) { // flat array of integers (JS or typed array) - - _gl.uniform1iv( location, value ); - - } else if ( type === "iv" ) { // flat array of integers with 3 x N size (JS or typed array) - - _gl.uniform3iv( location, value ); - - } else if ( type === "fv1" ) { // flat array of floats (JS or typed array) - - _gl.uniform1fv( location, value ); - - } else if ( type === "fv" ) { // flat array of floats with 3 x N size (JS or typed array) - - _gl.uniform3fv( location, value ); - - } else if ( type === "v2v" ) { // array of THREE.Vector2 - - if ( uniform._array === undefined ) { - - uniform._array = new Float32Array( 2 * value.length ); - - } - - for ( i = 0, il = value.length; i < il; i ++ ) { - - offset = i * 2; - - uniform._array[ offset ] = value[ i ].x; - uniform._array[ offset + 1 ] = value[ i ].y; - - } - - _gl.uniform2fv( location, uniform._array ); - - } else if ( type === "v3v" ) { // array of THREE.Vector3 - - if ( uniform._array === undefined ) { - - uniform._array = new Float32Array( 3 * value.length ); - - } - - for ( i = 0, il = value.length; i < il; i ++ ) { - - offset = i * 3; - - uniform._array[ offset ] = value[ i ].x; - uniform._array[ offset + 1 ] = value[ i ].y; - uniform._array[ offset + 2 ] = value[ i ].z; - - } - - _gl.uniform3fv( location, uniform._array ); - - } else if ( type === "v4v" ) { // array of THREE.Vector4 - - if ( uniform._array === undefined ) { - - uniform._array = new Float32Array( 4 * value.length ); - - } - - for ( i = 0, il = value.length; i < il; i ++ ) { - - offset = i * 4; - - uniform._array[ offset ] = value[ i ].x; - uniform._array[ offset + 1 ] = value[ i ].y; - uniform._array[ offset + 2 ] = value[ i ].z; - uniform._array[ offset + 3 ] = value[ i ].w; - - } - - _gl.uniform4fv( location, uniform._array ); - - } else if ( type === "m3") { // single THREE.Matrix3 - - _gl.uniformMatrix3fv( location, false, value.elements ); - - } else if ( type === "m3v" ) { // array of THREE.Matrix3 - - if ( uniform._array === undefined ) { - - uniform._array = new Float32Array( 9 * value.length ); - - } - - for ( i = 0, il = value.length; i < il; i ++ ) { - - value[ i ].flattenToArrayOffset( uniform._array, i * 9 ); - - } - - _gl.uniformMatrix3fv( location, false, uniform._array ); - - } else if ( type === "m4") { // single THREE.Matrix4 - - _gl.uniformMatrix4fv( location, false, value.elements ); - - } else if ( type === "m4v" ) { // array of THREE.Matrix4 - - if ( uniform._array === undefined ) { - - uniform._array = new Float32Array( 16 * value.length ); - - } - - for ( i = 0, il = value.length; i < il; i ++ ) { - - value[ i ].flattenToArrayOffset( uniform._array, i * 16 ); - - } - - _gl.uniformMatrix4fv( location, false, uniform._array ); - - } else if ( type === "t" ) { // single THREE.Texture (2d or cube) - - texture = value; - textureUnit = getTextureUnit(); - - _gl.uniform1i( location, textureUnit ); - - if ( !texture ) continue; - - if ( texture.image instanceof Array && texture.image.length === 6 ) { - - setCubeTexture( texture, textureUnit ); - - } else if ( texture instanceof THREE.WebGLRenderTargetCube ) { - - setCubeTextureDynamic( texture, textureUnit ); - - } else { - - _this.setTexture( texture, textureUnit ); - - } - - } else if ( type === "tv" ) { // array of THREE.Texture (2d) - - if ( uniform._array === undefined ) { - - uniform._array = []; - - } - - for( i = 0, il = uniform.value.length; i < il; i ++ ) { - - uniform._array[ i ] = getTextureUnit(); - - } - - _gl.uniform1iv( location, uniform._array ); - - for( i = 0, il = uniform.value.length; i < il; i ++ ) { - - texture = uniform.value[ i ]; - textureUnit = uniform._array[ i ]; - - if ( !texture ) continue; - - _this.setTexture( texture, textureUnit ); - - } - - } else { - - console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type ); - - } - - } - - }; - - function setupMatrices ( object, camera ) { - - object._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); - object._normalMatrix.getNormalMatrix( object._modelViewMatrix ); - - }; - - // - - function setColorGamma( array, offset, color, intensitySq ) { - - array[ offset ] = color.r * color.r * intensitySq; - array[ offset + 1 ] = color.g * color.g * intensitySq; - array[ offset + 2 ] = color.b * color.b * intensitySq; - - }; - - function setColorLinear( array, offset, color, intensity ) { - - array[ offset ] = color.r * intensity; - array[ offset + 1 ] = color.g * intensity; - array[ offset + 2 ] = color.b * intensity; - - }; - - function setupLights ( program, lights ) { - - var l, ll, light, n, - r = 0, g = 0, b = 0, - color, skyColor, groundColor, - intensity, intensitySq, - position, - distance, - - zlights = _lights, - - dirColors = zlights.directional.colors, - dirPositions = zlights.directional.positions, - - pointColors = zlights.point.colors, - pointPositions = zlights.point.positions, - pointDistances = zlights.point.distances, - - spotColors = zlights.spot.colors, - spotPositions = zlights.spot.positions, - spotDistances = zlights.spot.distances, - spotDirections = zlights.spot.directions, - spotAnglesCos = zlights.spot.anglesCos, - spotExponents = zlights.spot.exponents, - - hemiSkyColors = zlights.hemi.skyColors, - hemiGroundColors = zlights.hemi.groundColors, - hemiPositions = zlights.hemi.positions, - - dirLength = 0, - pointLength = 0, - spotLength = 0, - hemiLength = 0, - - dirCount = 0, - pointCount = 0, - spotCount = 0, - hemiCount = 0, - - dirOffset = 0, - pointOffset = 0, - spotOffset = 0, - hemiOffset = 0; - - for ( l = 0, ll = lights.length; l < ll; l ++ ) { - - light = lights[ l ]; - - if ( light.onlyShadow ) continue; - - color = light.color; - intensity = light.intensity; - distance = light.distance; - - if ( light instanceof THREE.AmbientLight ) { - - if ( ! light.visible ) continue; - - if ( _this.gammaInput ) { - - r += color.r * color.r; - g += color.g * color.g; - b += color.b * color.b; - - } else { - - r += color.r; - g += color.g; - b += color.b; - - } - - } else if ( light instanceof THREE.DirectionalLight ) { - - dirCount += 1; - - if ( ! light.visible ) continue; - - _direction.setFromMatrixPosition( light.matrixWorld ); - _vector3.setFromMatrixPosition( light.target.matrixWorld ); - _direction.sub( _vector3 ); - _direction.normalize(); - - // skip lights with undefined direction - // these create troubles in OpenGL (making pixel black) - - if ( _direction.x === 0 && _direction.y === 0 && _direction.z === 0 ) continue; - - dirOffset = dirLength * 3; - - dirPositions[ dirOffset ] = _direction.x; - dirPositions[ dirOffset + 1 ] = _direction.y; - dirPositions[ dirOffset + 2 ] = _direction.z; - - if ( _this.gammaInput ) { - - setColorGamma( dirColors, dirOffset, color, intensity * intensity ); - - } else { - - setColorLinear( dirColors, dirOffset, color, intensity ); - - } - - dirLength += 1; - - } else if ( light instanceof THREE.PointLight ) { - - pointCount += 1; - - if ( ! light.visible ) continue; - - pointOffset = pointLength * 3; - - if ( _this.gammaInput ) { - - setColorGamma( pointColors, pointOffset, color, intensity * intensity ); - - } else { - - setColorLinear( pointColors, pointOffset, color, intensity ); - - } - - _vector3.setFromMatrixPosition( light.matrixWorld ); - - pointPositions[ pointOffset ] = _vector3.x; - pointPositions[ pointOffset + 1 ] = _vector3.y; - pointPositions[ pointOffset + 2 ] = _vector3.z; - - pointDistances[ pointLength ] = distance; - - pointLength += 1; - - } else if ( light instanceof THREE.SpotLight ) { - - spotCount += 1; - - if ( ! light.visible ) continue; - - spotOffset = spotLength * 3; - - if ( _this.gammaInput ) { - - setColorGamma( spotColors, spotOffset, color, intensity * intensity ); - - } else { - - setColorLinear( spotColors, spotOffset, color, intensity ); - - } - - _vector3.setFromMatrixPosition( light.matrixWorld ); - - spotPositions[ spotOffset ] = _vector3.x; - spotPositions[ spotOffset + 1 ] = _vector3.y; - spotPositions[ spotOffset + 2 ] = _vector3.z; - - spotDistances[ spotLength ] = distance; - - _direction.copy( _vector3 ); - _vector3.setFromMatrixPosition( light.target.matrixWorld ); - _direction.sub( _vector3 ); - _direction.normalize(); - - spotDirections[ spotOffset ] = _direction.x; - spotDirections[ spotOffset + 1 ] = _direction.y; - spotDirections[ spotOffset + 2 ] = _direction.z; - - spotAnglesCos[ spotLength ] = Math.cos( light.angle ); - spotExponents[ spotLength ] = light.exponent; - - spotLength += 1; - - } else if ( light instanceof THREE.HemisphereLight ) { - - hemiCount += 1; - - if ( ! light.visible ) continue; - - _direction.setFromMatrixPosition( light.matrixWorld ); - _direction.normalize(); - - // skip lights with undefined direction - // these create troubles in OpenGL (making pixel black) - - if ( _direction.x === 0 && _direction.y === 0 && _direction.z === 0 ) continue; - - hemiOffset = hemiLength * 3; - - hemiPositions[ hemiOffset ] = _direction.x; - hemiPositions[ hemiOffset + 1 ] = _direction.y; - hemiPositions[ hemiOffset + 2 ] = _direction.z; - - skyColor = light.color; - groundColor = light.groundColor; - - if ( _this.gammaInput ) { - - intensitySq = intensity * intensity; - - setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensitySq ); - setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensitySq ); - - } else { - - setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity ); - setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity ); - - } - - hemiLength += 1; - - } - - } - - // null eventual remains from removed lights - // (this is to avoid if in shader) - - for ( l = dirLength * 3, ll = Math.max( dirColors.length, dirCount * 3 ); l < ll; l ++ ) dirColors[ l ] = 0.0; - for ( l = pointLength * 3, ll = Math.max( pointColors.length, pointCount * 3 ); l < ll; l ++ ) pointColors[ l ] = 0.0; - for ( l = spotLength * 3, ll = Math.max( spotColors.length, spotCount * 3 ); l < ll; l ++ ) spotColors[ l ] = 0.0; - for ( l = hemiLength * 3, ll = Math.max( hemiSkyColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiSkyColors[ l ] = 0.0; - for ( l = hemiLength * 3, ll = Math.max( hemiGroundColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiGroundColors[ l ] = 0.0; - - zlights.directional.length = dirLength; - zlights.point.length = pointLength; - zlights.spot.length = spotLength; - zlights.hemi.length = hemiLength; - - zlights.ambient[ 0 ] = r; - zlights.ambient[ 1 ] = g; - zlights.ambient[ 2 ] = b; - - }; - - // GL state setting - - this.setFaceCulling = function ( cullFace, frontFaceDirection ) { - - if ( cullFace === THREE.CullFaceNone ) { - - _gl.disable( _gl.CULL_FACE ); - - } else { - - if ( frontFaceDirection === THREE.FrontFaceDirectionCW ) { - - _gl.frontFace( _gl.CW ); - - } else { - - _gl.frontFace( _gl.CCW ); - - } - - if ( cullFace === THREE.CullFaceBack ) { - - _gl.cullFace( _gl.BACK ); - - } else if ( cullFace === THREE.CullFaceFront ) { - - _gl.cullFace( _gl.FRONT ); - - } else { - - _gl.cullFace( _gl.FRONT_AND_BACK ); - - } - - _gl.enable( _gl.CULL_FACE ); - - } - - }; - - this.setMaterialFaces = function ( material ) { - - var doubleSided = material.side === THREE.DoubleSide; - var flipSided = material.side === THREE.BackSide; - - if ( _oldDoubleSided !== doubleSided ) { - - if ( doubleSided ) { - - _gl.disable( _gl.CULL_FACE ); - - } else { - - _gl.enable( _gl.CULL_FACE ); - - } - - _oldDoubleSided = doubleSided; - - } - - if ( _oldFlipSided !== flipSided ) { - - if ( flipSided ) { - - _gl.frontFace( _gl.CW ); - - } else { - - _gl.frontFace( _gl.CCW ); - - } - - _oldFlipSided = flipSided; - - } - - }; - - this.setDepthTest = function ( depthTest ) { - - if ( _oldDepthTest !== depthTest ) { - - if ( depthTest ) { - - _gl.enable( _gl.DEPTH_TEST ); - - } else { - - _gl.disable( _gl.DEPTH_TEST ); - - } - - _oldDepthTest = depthTest; - - } - - }; - - this.setDepthWrite = function ( depthWrite ) { - - if ( _oldDepthWrite !== depthWrite ) { - - _gl.depthMask( depthWrite ); - _oldDepthWrite = depthWrite; - - } - - }; - - function setLineWidth ( width ) { - - if ( width !== _oldLineWidth ) { - - _gl.lineWidth( width ); - - _oldLineWidth = width; - - } - - }; - - function setPolygonOffset ( polygonoffset, factor, units ) { - - if ( _oldPolygonOffset !== polygonoffset ) { - - if ( polygonoffset ) { - - _gl.enable( _gl.POLYGON_OFFSET_FILL ); - - } else { - - _gl.disable( _gl.POLYGON_OFFSET_FILL ); - - } - - _oldPolygonOffset = polygonoffset; - - } - - if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) { - - _gl.polygonOffset( factor, units ); - - _oldPolygonOffsetFactor = factor; - _oldPolygonOffsetUnits = units; - - } - - }; - - this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) { - - if ( blending !== _oldBlending ) { - - if ( blending === THREE.NoBlending ) { - - _gl.disable( _gl.BLEND ); - - } else if ( blending === THREE.AdditiveBlending ) { - - _gl.enable( _gl.BLEND ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE ); - - } else if ( blending === THREE.SubtractiveBlending ) { - - // TODO: Find blendFuncSeparate() combination - _gl.enable( _gl.BLEND ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR ); - - } else if ( blending === THREE.MultiplyBlending ) { - - // TODO: Find blendFuncSeparate() combination - _gl.enable( _gl.BLEND ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR ); - - } else if ( blending === THREE.CustomBlending ) { - - _gl.enable( _gl.BLEND ); - - } else { - - _gl.enable( _gl.BLEND ); - _gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD ); - _gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA ); - - } - - _oldBlending = blending; - - } - - if ( blending === THREE.CustomBlending ) { - - if ( blendEquation !== _oldBlendEquation ) { - - _gl.blendEquation( paramThreeToGL( blendEquation ) ); - - _oldBlendEquation = blendEquation; - - } - - if ( blendSrc !== _oldBlendSrc || blendDst !== _oldBlendDst ) { - - _gl.blendFunc( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ) ); - - _oldBlendSrc = blendSrc; - _oldBlendDst = blendDst; - - } - - } else { - - _oldBlendEquation = null; - _oldBlendSrc = null; - _oldBlendDst = null; - - } - - }; - - // Textures - - function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) { - - if ( isImagePowerOfTwo ) { - - _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) ); - _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) ); - - _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) ); - _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) ); - - } else { - - _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE ); - _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE ); - - _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) ); - _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) ); - - } - - if ( _glExtensionTextureFilterAnisotropic && texture.type !== THREE.FloatType ) { - - if ( texture.anisotropy > 1 || texture.__oldAnisotropy ) { - - _gl.texParameterf( textureType, _glExtensionTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _maxAnisotropy ) ); - texture.__oldAnisotropy = texture.anisotropy; - - } - - } - - }; - - this.setTexture = function ( texture, slot ) { - - if ( texture.needsUpdate ) { - - if ( ! texture.__webglInit ) { - - texture.__webglInit = true; - - texture.addEventListener( 'dispose', onTextureDispose ); - - texture.__webglTexture = _gl.createTexture(); - - _this.info.memory.textures ++; - - } - - _gl.activeTexture( _gl.TEXTURE0 + slot ); - _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture ); - - _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); - _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ); - _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment ); - - var image = texture.image, - isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ), - glFormat = paramThreeToGL( texture.format ), - glType = paramThreeToGL( texture.type ); - - setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo ); - - var mipmap, mipmaps = texture.mipmaps; - - if ( texture instanceof THREE.DataTexture ) { - - // use manually created mipmaps if available - // if there are no manual mipmaps - // set 0 level mipmap and then use GL to generate other mipmap levels - - if ( mipmaps.length > 0 && isImagePowerOfTwo ) { - - for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { - - mipmap = mipmaps[ i ]; - _gl.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); - - } - - texture.generateMipmaps = false; - - } else { - - _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data ); - - } - - } else if ( texture instanceof THREE.CompressedTexture ) { - - for( var i = 0, il = mipmaps.length; i < il; i ++ ) { - - mipmap = mipmaps[ i ]; - if ( texture.format!==THREE.RGBAFormat ) { - _gl.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data ); - } else { - _gl.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); - } - - } - - } else { // regular Texture (image, video, canvas) - - // use manually created mipmaps if available - // if there are no manual mipmaps - // set 0 level mipmap and then use GL to generate other mipmap levels - - if ( mipmaps.length > 0 && isImagePowerOfTwo ) { - - for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { - - mipmap = mipmaps[ i ]; - _gl.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap ); - - } - - texture.generateMipmaps = false; - - } else { - - _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image ); - - } - - } - - if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D ); - - texture.needsUpdate = false; - - if ( texture.onUpdate ) texture.onUpdate(); - - } else { - - _gl.activeTexture( _gl.TEXTURE0 + slot ); - _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture ); - - } - - }; - - function clampToMaxSize ( image, maxSize ) { - - if ( image.width <= maxSize && image.height <= maxSize ) { - - return image; - - } - - // Warning: Scaling through the canvas will only work with images that use - // premultiplied alpha. - - var maxDimension = Math.max( image.width, image.height ); - var newWidth = Math.floor( image.width * maxSize / maxDimension ); - var newHeight = Math.floor( image.height * maxSize / maxDimension ); - - var canvas = document.createElement( 'canvas' ); - canvas.width = newWidth; - canvas.height = newHeight; - - var ctx = canvas.getContext( "2d" ); - ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight ); - - return canvas; - - } - - function setCubeTexture ( texture, slot ) { - - if ( texture.image.length === 6 ) { - - if ( texture.needsUpdate ) { - - if ( ! texture.image.__webglTextureCube ) { - - texture.addEventListener( 'dispose', onTextureDispose ); - - texture.image.__webglTextureCube = _gl.createTexture(); - - _this.info.memory.textures ++; - - } - - _gl.activeTexture( _gl.TEXTURE0 + slot ); - _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube ); - - _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); - - var isCompressed = texture instanceof THREE.CompressedTexture; - - var cubeImage = []; - - for ( var i = 0; i < 6; i ++ ) { - - if ( _this.autoScaleCubemaps && ! isCompressed ) { - - cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize ); - - } else { - - cubeImage[ i ] = texture.image[ i ]; - - } - - } - - var image = cubeImage[ 0 ], - isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ), - glFormat = paramThreeToGL( texture.format ), - glType = paramThreeToGL( texture.type ); - - setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo ); - - for ( var i = 0; i < 6; i ++ ) { - - if( !isCompressed ) { - - _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] ); - - } else { - - var mipmap, mipmaps = cubeImage[ i ].mipmaps; - - for( var j = 0, jl = mipmaps.length; j < jl; j ++ ) { - - mipmap = mipmaps[ j ]; - if ( texture.format!==THREE.RGBAFormat ) { - - _gl.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data ); - - } else { - _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); - } - - } - } - } - - if ( texture.generateMipmaps && isImagePowerOfTwo ) { - - _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP ); - - } - - texture.needsUpdate = false; - - if ( texture.onUpdate ) texture.onUpdate(); - - } else { - - _gl.activeTexture( _gl.TEXTURE0 + slot ); - _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube ); - - } - - } - - }; - - function setCubeTextureDynamic ( texture, slot ) { - - _gl.activeTexture( _gl.TEXTURE0 + slot ); - _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture ); - - }; - - // Render targets - - function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) { - - _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); - _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 ); - - }; - - function setupRenderBuffer ( renderbuffer, renderTarget ) { - - _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer ); - - if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) { - - _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height ); - _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); - - /* For some reason this is not working. Defaulting to RGBA4. - } else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) { - - _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height ); - _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); - */ - } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) { - - _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height ); - _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); - - } else { - - _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height ); - - } - - }; - - this.setRenderTarget = function ( renderTarget ) { - - var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube ); - - if ( renderTarget && ! renderTarget.__webglFramebuffer ) { - - if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true; - if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true; - - renderTarget.addEventListener( 'dispose', onRenderTargetDispose ); - - renderTarget.__webglTexture = _gl.createTexture(); - - _this.info.memory.textures ++; - - // Setup texture, create render and frame buffers - - var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height ), - glFormat = paramThreeToGL( renderTarget.format ), - glType = paramThreeToGL( renderTarget.type ); - - if ( isCube ) { - - renderTarget.__webglFramebuffer = []; - renderTarget.__webglRenderbuffer = []; - - _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture ); - setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo ); - - for ( var i = 0; i < 6; i ++ ) { - - renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer(); - renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer(); - - _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); - - setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i ); - setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget ); - - } - - if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP ); - - } else { - - renderTarget.__webglFramebuffer = _gl.createFramebuffer(); - - if ( renderTarget.shareDepthFrom ) { - - renderTarget.__webglRenderbuffer = renderTarget.shareDepthFrom.__webglRenderbuffer; - - } else { - - renderTarget.__webglRenderbuffer = _gl.createRenderbuffer(); - - } - - _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture ); - setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo ); - - _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); - - setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D ); - - if ( renderTarget.shareDepthFrom ) { - - if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) { - - _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTarget.__webglRenderbuffer ); - - } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) { - - _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTarget.__webglRenderbuffer ); - - } - - } else { - - setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget ); - - } - - if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D ); - - } - - // Release everything - - if ( isCube ) { - - _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null ); - - } else { - - _gl.bindTexture( _gl.TEXTURE_2D, null ); - - } - - _gl.bindRenderbuffer( _gl.RENDERBUFFER, null ); - _gl.bindFramebuffer( _gl.FRAMEBUFFER, null ); - - } - - var framebuffer, width, height, vx, vy; - - if ( renderTarget ) { - - if ( isCube ) { - - framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ]; - - } else { - - framebuffer = renderTarget.__webglFramebuffer; - - } - - width = renderTarget.width; - height = renderTarget.height; - - vx = 0; - vy = 0; - - } else { - - framebuffer = null; - - width = _viewportWidth; - height = _viewportHeight; - - vx = _viewportX; - vy = _viewportY; - - } - - if ( framebuffer !== _currentFramebuffer ) { - - _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); - _gl.viewport( vx, vy, width, height ); - - _currentFramebuffer = framebuffer; - - } - - _currentWidth = width; - _currentHeight = height; - - }; - - function updateRenderTargetMipmap ( renderTarget ) { - - if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) { - - _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture ); - _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP ); - _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null ); - - } else { - - _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture ); - _gl.generateMipmap( _gl.TEXTURE_2D ); - _gl.bindTexture( _gl.TEXTURE_2D, null ); - - } - - }; - - // Fallback filters for non-power-of-2 textures - - function filterFallback ( f ) { - - if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) { - - return _gl.NEAREST; - - } - - return _gl.LINEAR; - - }; - - // Map three.js constants to WebGL constants - - function paramThreeToGL ( p ) { - - if ( p === THREE.RepeatWrapping ) return _gl.REPEAT; - if ( p === THREE.ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE; - if ( p === THREE.MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT; - - if ( p === THREE.NearestFilter ) return _gl.NEAREST; - if ( p === THREE.NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST; - if ( p === THREE.NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR; - - if ( p === THREE.LinearFilter ) return _gl.LINEAR; - if ( p === THREE.LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST; - if ( p === THREE.LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR; - - if ( p === THREE.UnsignedByteType ) return _gl.UNSIGNED_BYTE; - if ( p === THREE.UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4; - if ( p === THREE.UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1; - if ( p === THREE.UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5; - - if ( p === THREE.ByteType ) return _gl.BYTE; - if ( p === THREE.ShortType ) return _gl.SHORT; - if ( p === THREE.UnsignedShortType ) return _gl.UNSIGNED_SHORT; - if ( p === THREE.IntType ) return _gl.INT; - if ( p === THREE.UnsignedIntType ) return _gl.UNSIGNED_INT; - if ( p === THREE.FloatType ) return _gl.FLOAT; - - if ( p === THREE.AlphaFormat ) return _gl.ALPHA; - if ( p === THREE.RGBFormat ) return _gl.RGB; - if ( p === THREE.RGBAFormat ) return _gl.RGBA; - if ( p === THREE.LuminanceFormat ) return _gl.LUMINANCE; - if ( p === THREE.LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA; - - if ( p === THREE.AddEquation ) return _gl.FUNC_ADD; - if ( p === THREE.SubtractEquation ) return _gl.FUNC_SUBTRACT; - if ( p === THREE.ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT; - - if ( p === THREE.ZeroFactor ) return _gl.ZERO; - if ( p === THREE.OneFactor ) return _gl.ONE; - if ( p === THREE.SrcColorFactor ) return _gl.SRC_COLOR; - if ( p === THREE.OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR; - if ( p === THREE.SrcAlphaFactor ) return _gl.SRC_ALPHA; - if ( p === THREE.OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA; - if ( p === THREE.DstAlphaFactor ) return _gl.DST_ALPHA; - if ( p === THREE.OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA; - - if ( p === THREE.DstColorFactor ) return _gl.DST_COLOR; - if ( p === THREE.OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR; - if ( p === THREE.SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE; - - if ( _glExtensionCompressedTextureS3TC !== undefined ) { - - if ( p === THREE.RGB_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGB_S3TC_DXT1_EXT; - if ( p === THREE.RGBA_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT1_EXT; - if ( p === THREE.RGBA_S3TC_DXT3_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT3_EXT; - if ( p === THREE.RGBA_S3TC_DXT5_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT5_EXT; - - } - - return 0; - - }; - - // Allocations - - function allocateBones ( object ) { - - if ( _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture ) { - - return 1024; - - } else { - - // default for when object is not specified - // ( for example when prebuilding shader - // to be used with multiple objects ) - // - // - leave some extra space for other uniforms - // - limit here is ANGLE's 254 max uniform vectors - // (up to 54 should be safe) - - var nVertexUniforms = _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS ); - var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 ); - - var maxBones = nVertexMatrices; - - if ( object !== undefined && object instanceof THREE.SkinnedMesh ) { - - maxBones = Math.min( object.skeleton.bones.length, maxBones ); - - if ( maxBones < object.skeleton.bones.length ) { - - console.warn( "WebGLRenderer: too many bones - " + object.skeleton.bones.length + ", this GPU supports just " + maxBones + " (try OpenGL instead of ANGLE)" ); - - } - - } - - return maxBones; - - } - - }; - - function allocateLights( lights ) { - - var dirLights = 0; - var pointLights = 0; - var spotLights = 0; - var hemiLights = 0; - - for ( var l = 0, ll = lights.length; l < ll; l ++ ) { - - var light = lights[ l ]; - - if ( light.onlyShadow || light.visible === false ) continue; - - if ( light instanceof THREE.DirectionalLight ) dirLights ++; - if ( light instanceof THREE.PointLight ) pointLights ++; - if ( light instanceof THREE.SpotLight ) spotLights ++; - if ( light instanceof THREE.HemisphereLight ) hemiLights ++; - - } - - return { 'directional' : dirLights, 'point' : pointLights, 'spot': spotLights, 'hemi': hemiLights }; - - }; - - function allocateShadows( lights ) { - - var maxShadows = 0; - - for ( var l = 0, ll = lights.length; l < ll; l++ ) { - - var light = lights[ l ]; - - if ( ! light.castShadow ) continue; - - if ( light instanceof THREE.SpotLight ) maxShadows ++; - if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++; - - } - - return maxShadows; - - }; - - // Initialization - - function initGL() { - - try { - - var attributes = { - alpha: _alpha, - depth: _depth, - stencil: _stencil, - antialias: _antialias, - premultipliedAlpha: _premultipliedAlpha, - preserveDrawingBuffer: _preserveDrawingBuffer - }; - - _gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes ); - - if ( _gl === null ) { - - throw 'Error creating WebGL context.'; - - } - - } catch ( error ) { - - console.error( error ); - - } - - _glExtensionTextureFloat = _gl.getExtension( 'OES_texture_float' ); - _glExtensionTextureFloatLinear = _gl.getExtension( 'OES_texture_float_linear' ); - _glExtensionStandardDerivatives = _gl.getExtension( 'OES_standard_derivatives' ); - - _glExtensionTextureFilterAnisotropic = _gl.getExtension( 'EXT_texture_filter_anisotropic' ) || _gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || _gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' ); - - _glExtensionCompressedTextureS3TC = _gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || _gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || _gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' ); - - _glExtensionElementIndexUint = _gl.getExtension( 'OES_element_index_uint' ); - - - if ( _glExtensionTextureFloat === null ) { - - console.log( 'THREE.WebGLRenderer: Float textures not supported.' ); - - } - - if ( _glExtensionStandardDerivatives === null ) { - - console.log( 'THREE.WebGLRenderer: Standard derivatives not supported.' ); - - } - - if ( _glExtensionTextureFilterAnisotropic === null ) { - - console.log( 'THREE.WebGLRenderer: Anisotropic texture filtering not supported.' ); - - } - - if ( _glExtensionCompressedTextureS3TC === null ) { - - console.log( 'THREE.WebGLRenderer: S3TC compressed textures not supported.' ); - - } - - if ( _glExtensionElementIndexUint === null ) { - - console.log( 'THREE.WebGLRenderer: elementindex as unsigned integer not supported.' ); - - } - - if ( _gl.getShaderPrecisionFormat === undefined ) { - - _gl.getShaderPrecisionFormat = function() { - - return { - "rangeMin" : 1, - "rangeMax" : 1, - "precision" : 1 - }; - - } - } - - if ( _logarithmicDepthBuffer ) { - - _glExtensionFragDepth = _gl.getExtension( 'EXT_frag_depth' ); - - } - - }; - - function setDefaultGLState () { - - _gl.clearColor( 0, 0, 0, 1 ); - _gl.clearDepth( 1 ); - _gl.clearStencil( 0 ); - - _gl.enable( _gl.DEPTH_TEST ); - _gl.depthFunc( _gl.LEQUAL ); - - _gl.frontFace( _gl.CCW ); - _gl.cullFace( _gl.BACK ); - _gl.enable( _gl.CULL_FACE ); - - _gl.enable( _gl.BLEND ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA ); - - _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight ); - - _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); - - }; - - // default plugins (order is important) - - this.shadowMapPlugin = new THREE.ShadowMapPlugin(); - this.addPrePlugin( this.shadowMapPlugin ); - - this.addPostPlugin( new THREE.SpritePlugin() ); - this.addPostPlugin( new THREE.LensFlarePlugin() ); - -}; - -/** - * @author szimek / https://github.com/szimek/ - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.WebGLRenderTarget = function ( width, height, options ) { - - this.width = width; - this.height = height; - - options = options || {}; - - this.wrapS = options.wrapS !== undefined ? options.wrapS : THREE.ClampToEdgeWrapping; - this.wrapT = options.wrapT !== undefined ? options.wrapT : THREE.ClampToEdgeWrapping; - - this.magFilter = options.magFilter !== undefined ? options.magFilter : THREE.LinearFilter; - this.minFilter = options.minFilter !== undefined ? options.minFilter : THREE.LinearMipMapLinearFilter; - - this.anisotropy = options.anisotropy !== undefined ? options.anisotropy : 1; - - this.offset = new THREE.Vector2( 0, 0 ); - this.repeat = new THREE.Vector2( 1, 1 ); - - this.format = options.format !== undefined ? options.format : THREE.RGBAFormat; - this.type = options.type !== undefined ? options.type : THREE.UnsignedByteType; - - this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; - this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; - - this.generateMipmaps = true; - - this.shareDepthFrom = null; - -}; - -THREE.WebGLRenderTarget.prototype = { - - constructor: THREE.WebGLRenderTarget, - - setSize: function ( width, height ) { - - this.width = width; - this.height = height; - - }, - - clone: function () { - - var tmp = new THREE.WebGLRenderTarget( this.width, this.height ); - - tmp.wrapS = this.wrapS; - tmp.wrapT = this.wrapT; - - tmp.magFilter = this.magFilter; - tmp.minFilter = this.minFilter; - - tmp.anisotropy = this.anisotropy; - - tmp.offset.copy( this.offset ); - tmp.repeat.copy( this.repeat ); - - tmp.format = this.format; - tmp.type = this.type; - - tmp.depthBuffer = this.depthBuffer; - tmp.stencilBuffer = this.stencilBuffer; - - tmp.generateMipmaps = this.generateMipmaps; - - tmp.shareDepthFrom = this.shareDepthFrom; - - return tmp; - - }, - - dispose: function () { - - this.dispatchEvent( { type: 'dispose' } ); - - } - -}; - -THREE.EventDispatcher.prototype.apply( THREE.WebGLRenderTarget.prototype ); - -/** - * @author alteredq / http://alteredqualia.com - */ - -THREE.WebGLRenderTargetCube = function ( width, height, options ) { - - THREE.WebGLRenderTarget.call( this, width, height, options ); - - this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5 - -}; - -THREE.WebGLRenderTargetCube.prototype = Object.create( THREE.WebGLRenderTarget.prototype ); - -THREE.WebGLProgram = ( function () { - - var programIdCount = 0; - - var generateDefines = function ( defines ) { - - var value, chunk, chunks = []; - - for ( var d in defines ) { - - value = defines[ d ]; - if ( value === false ) continue; - - chunk = "#define " + d + " " + value; - chunks.push( chunk ); - - } - - return chunks.join( "\n" ); - - }; - - var cacheUniformLocations = function ( gl, program, identifiers ) { - - var uniforms = {}; - - for ( var i = 0, l = identifiers.length; i < l; i ++ ) { - - var id = identifiers[ i ]; - uniforms[ id ] = gl.getUniformLocation( program, id ); - - } - - return uniforms; - - }; - - var cacheAttributeLocations = function ( gl, program, identifiers ) { - - var attributes = {}; - - for ( var i = 0, l = identifiers.length; i < l; i ++ ) { - - var id = identifiers[ i ]; - attributes[ id ] = gl.getAttribLocation( program, id ); - - } - - return attributes; - - }; - - return function ( renderer, code, material, parameters ) { - - var _this = renderer; - var _gl = _this.context; - - var fragmentShader = material.fragmentShader; - var vertexShader = material.vertexShader; - var uniforms = material.uniforms; - var attributes = material.attributes; - var defines = material.defines; - var index0AttributeName = material.index0AttributeName; - - if ( index0AttributeName === undefined && parameters.morphTargets === true ) { - - // programs with morphTargets displace position out of attribute 0 - - index0AttributeName = 'position'; - - } - - var shadowMapTypeDefine = "SHADOWMAP_TYPE_BASIC"; - - if ( parameters.shadowMapType === THREE.PCFShadowMap ) { - - shadowMapTypeDefine = "SHADOWMAP_TYPE_PCF"; - - } else if ( parameters.shadowMapType === THREE.PCFSoftShadowMap ) { - - shadowMapTypeDefine = "SHADOWMAP_TYPE_PCF_SOFT"; - - } - - // console.log( "building new program " ); - - // - - var customDefines = generateDefines( defines ); - - // - - var program = _gl.createProgram(); - - var prefix_vertex, prefix_fragment; - - if ( material instanceof THREE.RawShaderMaterial ) { - - prefix_vertex = ''; - prefix_fragment = ''; - - } else { - - prefix_vertex = [ - - "precision " + parameters.precision + " float;", - "precision " + parameters.precision + " int;", - - customDefines, - - parameters.supportsVertexTextures ? "#define VERTEX_TEXTURES" : "", - - _this.gammaInput ? "#define GAMMA_INPUT" : "", - _this.gammaOutput ? "#define GAMMA_OUTPUT" : "", - - "#define MAX_DIR_LIGHTS " + parameters.maxDirLights, - "#define MAX_POINT_LIGHTS " + parameters.maxPointLights, - "#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights, - "#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights, - - "#define MAX_SHADOWS " + parameters.maxShadows, - - "#define MAX_BONES " + parameters.maxBones, - - parameters.map ? "#define USE_MAP" : "", - parameters.envMap ? "#define USE_ENVMAP" : "", - parameters.lightMap ? "#define USE_LIGHTMAP" : "", - parameters.bumpMap ? "#define USE_BUMPMAP" : "", - parameters.normalMap ? "#define USE_NORMALMAP" : "", - parameters.specularMap ? "#define USE_SPECULARMAP" : "", - parameters.vertexColors ? "#define USE_COLOR" : "", - - parameters.skinning ? "#define USE_SKINNING" : "", - parameters.useVertexTexture ? "#define BONE_TEXTURE" : "", - - parameters.morphTargets ? "#define USE_MORPHTARGETS" : "", - parameters.morphNormals ? "#define USE_MORPHNORMALS" : "", - parameters.wrapAround ? "#define WRAP_AROUND" : "", - parameters.doubleSided ? "#define DOUBLE_SIDED" : "", - parameters.flipSided ? "#define FLIP_SIDED" : "", - - parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "", - parameters.shadowMapEnabled ? "#define " + shadowMapTypeDefine : "", - parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "", - parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "", - - parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "", - - parameters.logarithmicDepthBuffer ? "#define USE_LOGDEPTHBUF" : "", - //_this._glExtensionFragDepth ? "#define USE_LOGDEPTHBUF_EXT" : "", - - - "uniform mat4 modelMatrix;", - "uniform mat4 modelViewMatrix;", - "uniform mat4 projectionMatrix;", - "uniform mat4 viewMatrix;", - "uniform mat3 normalMatrix;", - "uniform vec3 cameraPosition;", - - "attribute vec3 position;", - "attribute vec3 normal;", - "attribute vec2 uv;", - "attribute vec2 uv2;", - - "#ifdef USE_COLOR", - - " attribute vec3 color;", - - "#endif", - - "#ifdef USE_MORPHTARGETS", - - " attribute vec3 morphTarget0;", - " attribute vec3 morphTarget1;", - " attribute vec3 morphTarget2;", - " attribute vec3 morphTarget3;", - - " #ifdef USE_MORPHNORMALS", - - " attribute vec3 morphNormal0;", - " attribute vec3 morphNormal1;", - " attribute vec3 morphNormal2;", - " attribute vec3 morphNormal3;", - - " #else", - - " attribute vec3 morphTarget4;", - " attribute vec3 morphTarget5;", - " attribute vec3 morphTarget6;", - " attribute vec3 morphTarget7;", - - " #endif", - - "#endif", - - "#ifdef USE_SKINNING", - - " attribute vec4 skinIndex;", - " attribute vec4 skinWeight;", - - "#endif", - - "" - - ].join( '\n' ); - - prefix_fragment = [ - - "precision " + parameters.precision + " float;", - "precision " + parameters.precision + " int;", - - ( parameters.bumpMap || parameters.normalMap ) ? "#extension GL_OES_standard_derivatives : enable" : "", - - customDefines, - - "#define MAX_DIR_LIGHTS " + parameters.maxDirLights, - "#define MAX_POINT_LIGHTS " + parameters.maxPointLights, - "#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights, - "#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights, - - "#define MAX_SHADOWS " + parameters.maxShadows, - - parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "", - - _this.gammaInput ? "#define GAMMA_INPUT" : "", - _this.gammaOutput ? "#define GAMMA_OUTPUT" : "", - - ( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "", - ( parameters.useFog && parameters.fogExp ) ? "#define FOG_EXP2" : "", - - parameters.map ? "#define USE_MAP" : "", - parameters.envMap ? "#define USE_ENVMAP" : "", - parameters.lightMap ? "#define USE_LIGHTMAP" : "", - parameters.bumpMap ? "#define USE_BUMPMAP" : "", - parameters.normalMap ? "#define USE_NORMALMAP" : "", - parameters.specularMap ? "#define USE_SPECULARMAP" : "", - parameters.vertexColors ? "#define USE_COLOR" : "", - - parameters.metal ? "#define METAL" : "", - parameters.wrapAround ? "#define WRAP_AROUND" : "", - parameters.doubleSided ? "#define DOUBLE_SIDED" : "", - parameters.flipSided ? "#define FLIP_SIDED" : "", - - parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "", - parameters.shadowMapEnabled ? "#define " + shadowMapTypeDefine : "", - parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "", - parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "", - - parameters.logarithmicDepthBuffer ? "#define USE_LOGDEPTHBUF" : "", - //_this._glExtensionFragDepth ? "#define USE_LOGDEPTHBUF_EXT" : "", - - "uniform mat4 viewMatrix;", - "uniform vec3 cameraPosition;", - "" - - ].join( '\n' ); - - } - - var glVertexShader = new THREE.WebGLShader( _gl, _gl.VERTEX_SHADER, prefix_vertex + vertexShader ); - var glFragmentShader = new THREE.WebGLShader( _gl, _gl.FRAGMENT_SHADER, prefix_fragment + fragmentShader ); - - _gl.attachShader( program, glVertexShader ); - _gl.attachShader( program, glFragmentShader ); - - if ( index0AttributeName !== undefined ) { - - // Force a particular attribute to index 0. - // because potentially expensive emulation is done by browser if attribute 0 is disabled. - // And, color, for example is often automatically bound to index 0 so disabling it - - _gl.bindAttribLocation( program, 0, index0AttributeName ); - - } - - _gl.linkProgram( program ); - - if ( _gl.getProgramParameter( program, _gl.LINK_STATUS ) === false ) { - - console.error( 'Could not initialise shader' ); - console.error( 'gl.VALIDATE_STATUS', _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) ); - console.error( 'gl.getError()', _gl.getError() ); - - } - - if ( _gl.getProgramInfoLog( program ) !== '' ) { - - console.error( 'gl.getProgramInfoLog()', _gl.getProgramInfoLog( program ) ); - - } - - // clean up - - _gl.deleteShader( glVertexShader ); - _gl.deleteShader( glFragmentShader ); - - // cache uniform locations - - var identifiers = [ - - 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'modelMatrix', 'cameraPosition', - 'morphTargetInfluences' - - ]; - - if ( parameters.useVertexTexture ) { - - identifiers.push( 'boneTexture' ); - identifiers.push( 'boneTextureWidth' ); - identifiers.push( 'boneTextureHeight' ); - - } else { - - identifiers.push( 'boneGlobalMatrices' ); - - } - - if ( parameters.logarithmicDepthBuffer ) { - - identifiers.push('logDepthBufFC'); - - } - - - for ( var u in uniforms ) { - - identifiers.push( u ); - - } - - this.uniforms = cacheUniformLocations( _gl, program, identifiers ); - - // cache attributes locations - - identifiers = [ - - "position", "normal", "uv", "uv2", "tangent", "color", - "skinIndex", "skinWeight", "lineDistance" - - ]; - - for ( var i = 0; i < parameters.maxMorphTargets; i ++ ) { - - identifiers.push( "morphTarget" + i ); - - } - - for ( var i = 0; i < parameters.maxMorphNormals; i ++ ) { - - identifiers.push( "morphNormal" + i ); - - } - - for ( var a in attributes ) { - - identifiers.push( a ); - - } - - this.attributes = cacheAttributeLocations( _gl, program, identifiers ); - - // - - this.id = programIdCount ++; - this.code = code; - this.usedTimes = 1; - this.program = program; - this.vertexShader = glVertexShader; - this.fragmentShader = glFragmentShader; - - return this; - - }; - -} )(); - -THREE.WebGLShader = ( function () { - - var addLineNumbers = function ( string ) { - - var lines = string.split( '\n' ); - - for ( var i = 0; i < lines.length; i ++ ) { - - lines[ i ] = ( i + 1 ) + ': ' + lines[ i ]; - - } - - return lines.join( '\n' ); - - }; - - return function ( gl, type, string ) { - - var shader = gl.createShader( type ); - - gl.shaderSource( shader, string ); - gl.compileShader( shader ); - - if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) { - - console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' ); - - } - - if ( gl.getShaderInfoLog( shader ) !== '' ) { - - console.error( 'THREE.WebGLShader:', 'gl.getShaderInfoLog()', gl.getShaderInfoLog( shader ) ); - console.error( addLineNumbers( string ) ); - - } - - // --enable-privileged-webgl-extension - // console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); - - return shader; - - }; - -} )(); -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.RenderableVertex = function () { - - this.position = new THREE.Vector3(); - this.positionWorld = new THREE.Vector3(); - this.positionScreen = new THREE.Vector4(); - - this.visible = true; - -}; - -THREE.RenderableVertex.prototype.copy = function ( vertex ) { - - this.positionWorld.copy( vertex.positionWorld ); - this.positionScreen.copy( vertex.positionScreen ); - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.RenderableFace = function () { - - this.id = 0; - - this.v1 = new THREE.RenderableVertex(); - this.v2 = new THREE.RenderableVertex(); - this.v3 = new THREE.RenderableVertex(); - - this.normalModel = new THREE.Vector3(); - - this.vertexNormalsModel = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ]; - this.vertexNormalsLength = 0; - - this.color = null; - this.material = null; - this.uvs = [ new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2() ]; - - this.z = 0; - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.RenderableObject = function () { - - this.id = 0; - - this.object = null; - this.z = 0; - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.RenderableSprite = function () { - - this.id = 0; - - this.object = null; - - this.x = 0; - this.y = 0; - this.z = 0; - - this.rotation = 0; - this.scale = new THREE.Vector2(); - - this.material = null; - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.RenderableLine = function () { - - this.id = 0; - - this.v1 = new THREE.RenderableVertex(); - this.v2 = new THREE.RenderableVertex(); - - this.vertexColors = [ new THREE.Color(), new THREE.Color() ]; - this.material = null; - - this.z = 0; - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.GeometryUtils = { - - // Merge two geometries or geometry and geometry from object (using object's transform) - - merge: function ( geometry1, geometry2, materialIndexOffset ) { - - console.warn( 'DEPRECATED: GeometryUtils\'s .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); - - var matrix; - - if ( geometry2 instanceof THREE.Mesh ) { - - geometry2.matrixAutoUpdate && geometry2.updateMatrix(); - - matrix = geometry2.matrix; - geometry2 = geometry2.geometry; - - } - - geometry1.merge( geometry2, matrix, materialIndexOffset ); - - }, - - // Get random point in triangle (via barycentric coordinates) - // (uniform distribution) - // http://www.cgafaq.info/wiki/Random_Point_In_Triangle - - randomPointInTriangle: function () { - - var vector = new THREE.Vector3(); - - return function ( vectorA, vectorB, vectorC ) { - - var point = new THREE.Vector3(); - - var a = THREE.Math.random16(); - var b = THREE.Math.random16(); - - if ( ( a + b ) > 1 ) { - - a = 1 - a; - b = 1 - b; - - } - - var c = 1 - a - b; - - point.copy( vectorA ); - point.multiplyScalar( a ); - - vector.copy( vectorB ); - vector.multiplyScalar( b ); - - point.add( vector ); - - vector.copy( vectorC ); - vector.multiplyScalar( c ); - - point.add( vector ); - - return point; - - }; - - }(), - - // Get random point in face (triangle) - // (uniform distribution) - - randomPointInFace: function ( face, geometry, useCachedAreas ) { - - var vA, vB, vC; - - vA = geometry.vertices[ face.a ]; - vB = geometry.vertices[ face.b ]; - vC = geometry.vertices[ face.c ]; - - return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vC ); - - }, - - // Get uniformly distributed random points in mesh - // - create array with cumulative sums of face areas - // - pick random number from 0 to total area - // - find corresponding place in area array by binary search - // - get random point in face - - randomPointsInGeometry: function ( geometry, n ) { - - var face, i, - faces = geometry.faces, - vertices = geometry.vertices, - il = faces.length, - totalArea = 0, - cumulativeAreas = [], - vA, vB, vC, vD; - - // precompute face areas - - for ( i = 0; i < il; i ++ ) { - - face = faces[ i ]; - - vA = vertices[ face.a ]; - vB = vertices[ face.b ]; - vC = vertices[ face.c ]; - - face._area = THREE.GeometryUtils.triangleArea( vA, vB, vC ); - - totalArea += face._area; - - cumulativeAreas[ i ] = totalArea; - - } - - // binary search cumulative areas array - - function binarySearchIndices( value ) { - - function binarySearch( start, end ) { - - // return closest larger index - // if exact number is not found - - if ( end < start ) - return start; - - var mid = start + Math.floor( ( end - start ) / 2 ); - - if ( cumulativeAreas[ mid ] > value ) { - - return binarySearch( start, mid - 1 ); - - } else if ( cumulativeAreas[ mid ] < value ) { - - return binarySearch( mid + 1, end ); - - } else { - - return mid; - - } - - } - - var result = binarySearch( 0, cumulativeAreas.length - 1 ) - return result; - - } - - // pick random face weighted by face area - - var r, index, - result = []; - - var stats = {}; - - for ( i = 0; i < n; i ++ ) { - - r = THREE.Math.random16() * totalArea; - - index = binarySearchIndices( r ); - - result[ i ] = THREE.GeometryUtils.randomPointInFace( faces[ index ], geometry, true ); - - if ( ! stats[ index ] ) { - - stats[ index ] = 1; - - } else { - - stats[ index ] += 1; - - } - - } - - return result; - - }, - - // Get triangle area (half of parallelogram) - // http://mathworld.wolfram.com/TriangleArea.html - - triangleArea: function () { - - var vector1 = new THREE.Vector3(); - var vector2 = new THREE.Vector3(); - - return function ( vectorA, vectorB, vectorC ) { - - vector1.subVectors( vectorB, vectorA ); - vector2.subVectors( vectorC, vectorA ); - vector1.cross( vector2 ); - - return 0.5 * vector1.length(); - - }; - - }(), - - // Center geometry so that 0,0,0 is in center of bounding box - - center: function ( geometry ) { - - geometry.computeBoundingBox(); - - var bb = geometry.boundingBox; - - var offset = new THREE.Vector3(); - - offset.addVectors( bb.min, bb.max ); - offset.multiplyScalar( -0.5 ); - - geometry.applyMatrix( new THREE.Matrix4().makeTranslation( offset.x, offset.y, offset.z ) ); - geometry.computeBoundingBox(); - - return offset; - - } - -}; - -/** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.ImageUtils = { - - crossOrigin: undefined, - - loadTexture: function ( url, mapping, onLoad, onError ) { - - var loader = new THREE.ImageLoader(); - loader.crossOrigin = this.crossOrigin; - - var texture = new THREE.Texture( undefined, mapping ); - - var image = loader.load( url, function () { - - texture.needsUpdate = true; - - if ( onLoad ) onLoad( texture ); - - }, undefined, function ( event ) { - - if ( onError ) onError( event ); - - } ); - - texture.image = image; - texture.sourceFile = url; - - return texture; - - }, - - loadCompressedTexture: function ( url, mapping, onLoad, onError ) { - - var texture = new THREE.CompressedTexture(); - texture.mapping = mapping; - - var request = new XMLHttpRequest(); - - request.onload = function () { - - var buffer = request.response; - var dds = THREE.ImageUtils.parseDDS( buffer, true ); - - texture.format = dds.format; - - texture.mipmaps = dds.mipmaps; - texture.image.width = dds.width; - texture.image.height = dds.height; - - // gl.generateMipmap fails for compressed textures - // mipmaps must be embedded in the DDS file - // or texture filters must not use mipmapping - - texture.generateMipmaps = false; - - texture.needsUpdate = true; - - if ( onLoad ) onLoad( texture ); - - } - - request.onerror = onError; - - request.open( 'GET', url, true ); - request.responseType = "arraybuffer"; - request.send( null ); - - return texture; - - }, - - loadTextureCube: function ( array, mapping, onLoad, onError ) { - - var images = []; - images.loadCount = 0; - - var loader = new THREE.ImageLoader(); - loader.crossOrigin = this.crossOrigin; - - var texture = new THREE.Texture(); - texture.image = images; - - if ( mapping !== undefined ) texture.mapping = mapping; - - // no flipping needed for cube textures - - texture.flipY = false; - - for ( var i = 0, il = array.length; i < il; ++ i ) { - - var cubeImage = loader.load( array[i], function () { - - images.loadCount += 1; - - if ( images.loadCount === 6 ) { - - texture.needsUpdate = true; - if ( onLoad ) onLoad( texture ); - - } - - } ); - - images[ i ] = cubeImage; - } - - return texture; - - }, - - loadCompressedTextureCube: function ( array, mapping, onLoad, onError ) { - - var images = []; - images.loadCount = 0; - - var texture = new THREE.CompressedTexture(); - texture.image = images; - if ( mapping !== undefined ) texture.mapping = mapping; - - // no flipping for cube textures - // (also flipping doesn't work for compressed textures ) - - texture.flipY = false; - - // can't generate mipmaps for compressed textures - // mips must be embedded in DDS files - - texture.generateMipmaps = false; - - var generateCubeFaceCallback = function ( rq, img ) { - - return function () { - - var buffer = rq.response; - var dds = THREE.ImageUtils.parseDDS( buffer, true ); - - img.format = dds.format; - - img.mipmaps = dds.mipmaps; - img.width = dds.width; - img.height = dds.height; - - images.loadCount += 1; - - if ( images.loadCount === 6 ) { - - texture.format = dds.format; - texture.needsUpdate = true; - if ( onLoad ) onLoad( texture ); - - } - - } - - } - - // compressed cubemap textures as 6 separate DDS files - - if ( array instanceof Array ) { - - for ( var i = 0, il = array.length; i < il; ++ i ) { - - var cubeImage = {}; - images[ i ] = cubeImage; - - var request = new XMLHttpRequest(); - - request.onload = generateCubeFaceCallback( request, cubeImage ); - request.onerror = onError; - - var url = array[ i ]; - - request.open( 'GET', url, true ); - request.responseType = "arraybuffer"; - request.send( null ); - - } - - // compressed cubemap texture stored in a single DDS file - - } else { - - var url = array; - var request = new XMLHttpRequest(); - - request.onload = function( ) { - - var buffer = request.response; - var dds = THREE.ImageUtils.parseDDS( buffer, true ); - - if ( dds.isCubemap ) { - - var faces = dds.mipmaps.length / dds.mipmapCount; - - for ( var f = 0; f < faces; f ++ ) { - - images[ f ] = { mipmaps : [] }; - - for ( var i = 0; i < dds.mipmapCount; i ++ ) { - - images[ f ].mipmaps.push( dds.mipmaps[ f * dds.mipmapCount + i ] ); - images[ f ].format = dds.format; - images[ f ].width = dds.width; - images[ f ].height = dds.height; - - } - - } - - texture.format = dds.format; - texture.needsUpdate = true; - if ( onLoad ) onLoad( texture ); - - } - - } - - request.onerror = onError; - - request.open( 'GET', url, true ); - request.responseType = "arraybuffer"; - request.send( null ); - - } - - return texture; - - }, - - loadDDSTexture: function ( url, mapping, onLoad, onError ) { - - var images = []; - images.loadCount = 0; - - var texture = new THREE.CompressedTexture(); - texture.image = images; - if ( mapping !== undefined ) texture.mapping = mapping; - - // no flipping for cube textures - // (also flipping doesn't work for compressed textures ) - - texture.flipY = false; - - // can't generate mipmaps for compressed textures - // mips must be embedded in DDS files - - texture.generateMipmaps = false; - - { - var request = new XMLHttpRequest(); - - request.onload = function( ) { - - var buffer = request.response; - var dds = THREE.ImageUtils.parseDDS( buffer, true ); - - if ( dds.isCubemap ) { - - var faces = dds.mipmaps.length / dds.mipmapCount; - - for ( var f = 0; f < faces; f ++ ) { - - images[ f ] = { mipmaps : [] }; - - for ( var i = 0; i < dds.mipmapCount; i ++ ) { - - images[ f ].mipmaps.push( dds.mipmaps[ f * dds.mipmapCount + i ] ); - images[ f ].format = dds.format; - images[ f ].width = dds.width; - images[ f ].height = dds.height; - - } - - } - - - } else { - texture.image.width = dds.width; - texture.image.height = dds.height; - texture.mipmaps = dds.mipmaps; - } - - texture.format = dds.format; - texture.needsUpdate = true; - if ( onLoad ) onLoad( texture ); - - } - - request.onerror = onError; - - request.open( 'GET', url, true ); - request.responseType = "arraybuffer"; - request.send( null ); - - } - - return texture; - - }, - - parseDDS: function ( buffer, loadMipmaps ) { - - var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 }; - - // Adapted from @toji's DDS utils - // https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js - - // All values and structures referenced from: - // http://msdn.microsoft.com/en-us/library/bb943991.aspx/ - - var DDS_MAGIC = 0x20534444; - - var DDSD_CAPS = 0x1, - DDSD_HEIGHT = 0x2, - DDSD_WIDTH = 0x4, - DDSD_PITCH = 0x8, - DDSD_PIXELFORMAT = 0x1000, - DDSD_MIPMAPCOUNT = 0x20000, - DDSD_LINEARSIZE = 0x80000, - DDSD_DEPTH = 0x800000; - - var DDSCAPS_COMPLEX = 0x8, - DDSCAPS_MIPMAP = 0x400000, - DDSCAPS_TEXTURE = 0x1000; - - var DDSCAPS2_CUBEMAP = 0x200, - DDSCAPS2_CUBEMAP_POSITIVEX = 0x400, - DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800, - DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000, - DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000, - DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000, - DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000, - DDSCAPS2_VOLUME = 0x200000; - - var DDPF_ALPHAPIXELS = 0x1, - DDPF_ALPHA = 0x2, - DDPF_FOURCC = 0x4, - DDPF_RGB = 0x40, - DDPF_YUV = 0x200, - DDPF_LUMINANCE = 0x20000; - - function fourCCToInt32( value ) { - - return value.charCodeAt(0) + - (value.charCodeAt(1) << 8) + - (value.charCodeAt(2) << 16) + - (value.charCodeAt(3) << 24); - - } - - function int32ToFourCC( value ) { - - return String.fromCharCode( - value & 0xff, - (value >> 8) & 0xff, - (value >> 16) & 0xff, - (value >> 24) & 0xff - ); - } - - function loadARGBMip( buffer, dataOffset, width, height ) { - var dataLength = width*height*4; - var srcBuffer = new Uint8Array( buffer, dataOffset, dataLength ); - var byteArray = new Uint8Array( dataLength ); - var dst = 0; - var src = 0; - for ( var y = 0; y < height; y++ ) { - for ( var x = 0; x < width; x++ ) { - var b = srcBuffer[src]; src++; - var g = srcBuffer[src]; src++; - var r = srcBuffer[src]; src++; - var a = srcBuffer[src]; src++; - byteArray[dst] = r; dst++; //r - byteArray[dst] = g; dst++; //g - byteArray[dst] = b; dst++; //b - byteArray[dst] = a; dst++; //a - } - } - return byteArray; - } - - var FOURCC_DXT1 = fourCCToInt32("DXT1"); - var FOURCC_DXT3 = fourCCToInt32("DXT3"); - var FOURCC_DXT5 = fourCCToInt32("DXT5"); - - var headerLengthInt = 31; // The header length in 32 bit ints - - // Offsets into the header array - - var off_magic = 0; - - var off_size = 1; - var off_flags = 2; - var off_height = 3; - var off_width = 4; - - var off_mipmapCount = 7; - - var off_pfFlags = 20; - var off_pfFourCC = 21; - var off_RGBBitCount = 22; - var off_RBitMask = 23; - var off_GBitMask = 24; - var off_BBitMask = 25; - var off_ABitMask = 26; - - var off_caps = 27; - var off_caps2 = 28; - var off_caps3 = 29; - var off_caps4 = 30; - - // Parse header - - var header = new Int32Array( buffer, 0, headerLengthInt ); - - if ( header[ off_magic ] !== DDS_MAGIC ) { - - console.error( "ImageUtils.parseDDS(): Invalid magic number in DDS header" ); - return dds; - - } - - if ( ! header[ off_pfFlags ] & DDPF_FOURCC ) { - - console.error( "ImageUtils.parseDDS(): Unsupported format, must contain a FourCC code" ); - return dds; - - } - - var blockBytes; - - var fourCC = header[ off_pfFourCC ]; - - var isRGBAUncompressed = false; - - switch ( fourCC ) { - - case FOURCC_DXT1: - - blockBytes = 8; - dds.format = THREE.RGB_S3TC_DXT1_Format; - break; - - case FOURCC_DXT3: - - blockBytes = 16; - dds.format = THREE.RGBA_S3TC_DXT3_Format; - break; - - case FOURCC_DXT5: - - blockBytes = 16; - dds.format = THREE.RGBA_S3TC_DXT5_Format; - break; - - default: - - if( header[off_RGBBitCount] ==32 - && header[off_RBitMask]&0xff0000 - && header[off_GBitMask]&0xff00 - && header[off_BBitMask]&0xff - && header[off_ABitMask]&0xff000000 ) { - isRGBAUncompressed = true; - blockBytes = 64; - dds.format = THREE.RGBAFormat; - } else { - console.error( "ImageUtils.parseDDS(): Unsupported FourCC code: ", int32ToFourCC( fourCC ) ); - return dds; - } - } - - dds.mipmapCount = 1; - - if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) { - - dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] ); - - } - - //TODO: Verify that all faces of the cubemap are present with DDSCAPS2_CUBEMAP_POSITIVEX, etc. - - dds.isCubemap = header[ off_caps2 ] & DDSCAPS2_CUBEMAP ? true : false; - - dds.width = header[ off_width ]; - dds.height = header[ off_height ]; - - var dataOffset = header[ off_size ] + 4; - - // Extract mipmaps buffers - - var width = dds.width; - var height = dds.height; - - var faces = dds.isCubemap ? 6 : 1; - - for ( var face = 0; face < faces; face ++ ) { - - for ( var i = 0; i < dds.mipmapCount; i ++ ) { - - if( isRGBAUncompressed ) { - var byteArray = loadARGBMip( buffer, dataOffset, width, height ); - var dataLength = byteArray.length; - } else { - var dataLength = Math.max( 4, width ) / 4 * Math.max( 4, height ) / 4 * blockBytes; - var byteArray = new Uint8Array( buffer, dataOffset, dataLength ); - } - - var mipmap = { "data": byteArray, "width": width, "height": height }; - dds.mipmaps.push( mipmap ); - - dataOffset += dataLength; - - width = Math.max( width * 0.5, 1 ); - height = Math.max( height * 0.5, 1 ); - - } - - width = dds.width; - height = dds.height; - - } - - return dds; - - }, - - getNormalMap: function ( image, depth ) { - - // Adapted from http://www.paulbrunt.co.uk/lab/heightnormal/ - - var cross = function ( a, b ) { - - return [ a[ 1 ] * b[ 2 ] - a[ 2 ] * b[ 1 ], a[ 2 ] * b[ 0 ] - a[ 0 ] * b[ 2 ], a[ 0 ] * b[ 1 ] - a[ 1 ] * b[ 0 ] ]; - - } - - var subtract = function ( a, b ) { - - return [ a[ 0 ] - b[ 0 ], a[ 1 ] - b[ 1 ], a[ 2 ] - b[ 2 ] ]; - - } - - var normalize = function ( a ) { - - var l = Math.sqrt( a[ 0 ] * a[ 0 ] + a[ 1 ] * a[ 1 ] + a[ 2 ] * a[ 2 ] ); - return [ a[ 0 ] / l, a[ 1 ] / l, a[ 2 ] / l ]; - - } - - depth = depth | 1; - - var width = image.width; - var height = image.height; - - var canvas = document.createElement( 'canvas' ); - canvas.width = width; - canvas.height = height; - - var context = canvas.getContext( '2d' ); - context.drawImage( image, 0, 0 ); - - var data = context.getImageData( 0, 0, width, height ).data; - var imageData = context.createImageData( width, height ); - var output = imageData.data; - - for ( var x = 0; x < width; x ++ ) { - - for ( var y = 0; y < height; y ++ ) { - - var ly = y - 1 < 0 ? 0 : y - 1; - var uy = y + 1 > height - 1 ? height - 1 : y + 1; - var lx = x - 1 < 0 ? 0 : x - 1; - var ux = x + 1 > width - 1 ? width - 1 : x + 1; - - var points = []; - var origin = [ 0, 0, data[ ( y * width + x ) * 4 ] / 255 * depth ]; - points.push( [ - 1, 0, data[ ( y * width + lx ) * 4 ] / 255 * depth ] ); - points.push( [ - 1, - 1, data[ ( ly * width + lx ) * 4 ] / 255 * depth ] ); - points.push( [ 0, - 1, data[ ( ly * width + x ) * 4 ] / 255 * depth ] ); - points.push( [ 1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] ); - points.push( [ 1, 0, data[ ( y * width + ux ) * 4 ] / 255 * depth ] ); - points.push( [ 1, 1, data[ ( uy * width + ux ) * 4 ] / 255 * depth ] ); - points.push( [ 0, 1, data[ ( uy * width + x ) * 4 ] / 255 * depth ] ); - points.push( [ - 1, 1, data[ ( uy * width + lx ) * 4 ] / 255 * depth ] ); - - var normals = []; - var num_points = points.length; - - for ( var i = 0; i < num_points; i ++ ) { - - var v1 = points[ i ]; - var v2 = points[ ( i + 1 ) % num_points ]; - v1 = subtract( v1, origin ); - v2 = subtract( v2, origin ); - normals.push( normalize( cross( v1, v2 ) ) ); - - } - - var normal = [ 0, 0, 0 ]; - - for ( var i = 0; i < normals.length; i ++ ) { - - normal[ 0 ] += normals[ i ][ 0 ]; - normal[ 1 ] += normals[ i ][ 1 ]; - normal[ 2 ] += normals[ i ][ 2 ]; - - } - - normal[ 0 ] /= normals.length; - normal[ 1 ] /= normals.length; - normal[ 2 ] /= normals.length; - - var idx = ( y * width + x ) * 4; - - output[ idx ] = ( ( normal[ 0 ] + 1.0 ) / 2.0 * 255 ) | 0; - output[ idx + 1 ] = ( ( normal[ 1 ] + 1.0 ) / 2.0 * 255 ) | 0; - output[ idx + 2 ] = ( normal[ 2 ] * 255 ) | 0; - output[ idx + 3 ] = 255; - - } - - } - - context.putImageData( imageData, 0, 0 ); - - return canvas; - - }, - - generateDataTexture: function ( width, height, color ) { - - var size = width * height; - var data = new Uint8Array( 3 * size ); - - var r = Math.floor( color.r * 255 ); - var g = Math.floor( color.g * 255 ); - var b = Math.floor( color.b * 255 ); - - for ( var i = 0; i < size; i ++ ) { - - data[ i * 3 ] = r; - data[ i * 3 + 1 ] = g; - data[ i * 3 + 2 ] = b; - - } - - var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat ); - texture.needsUpdate = true; - - return texture; - - } - -}; - -/** - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.SceneUtils = { - - createMultiMaterialObject: function ( geometry, materials ) { - - var group = new THREE.Object3D(); - - for ( var i = 0, l = materials.length; i < l; i ++ ) { - - group.add( new THREE.Mesh( geometry, materials[ i ] ) ); - - } - - return group; - - }, - - detach : function ( child, parent, scene ) { - - child.applyMatrix( parent.matrixWorld ); - parent.remove( child ); - scene.add( child ); - - }, - - attach: function ( child, scene, parent ) { - - var matrixWorldInverse = new THREE.Matrix4(); - matrixWorldInverse.getInverse( parent.matrixWorld ); - child.applyMatrix( matrixWorldInverse ); - - scene.remove( child ); - parent.add( child ); - - } - -}; - -/** - * @author zz85 / http://www.lab4games.net/zz85/blog - * @author alteredq / http://alteredqualia.com/ - * - * For Text operations in three.js (See TextGeometry) - * - * It uses techniques used in: - * - * typeface.js and canvastext - * For converting fonts and rendering with javascript - * http://typeface.neocracy.org - * - * Triangulation ported from AS3 - * Simple Polygon Triangulation - * http://actionsnippet.com/?p=1462 - * - * A Method to triangulate shapes with holes - * http://www.sakri.net/blog/2009/06/12/an-approach-to-triangulating-polygons-with-holes/ - * - */ - -THREE.FontUtils = { - - faces : {}, - - // Just for now. face[weight][style] - - face : "helvetiker", - weight: "normal", - style : "normal", - size : 150, - divisions : 10, - - getFace : function() { - - return this.faces[ this.face ][ this.weight ][ this.style ]; - - }, - - loadFace : function( data ) { - - var family = data.familyName.toLowerCase(); - - var ThreeFont = this; - - ThreeFont.faces[ family ] = ThreeFont.faces[ family ] || {}; - - ThreeFont.faces[ family ][ data.cssFontWeight ] = ThreeFont.faces[ family ][ data.cssFontWeight ] || {}; - ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data; - - var face = ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data; - - return data; - - }, - - drawText : function( text ) { - - var characterPts = [], allPts = []; - - // RenderText - - var i, p, - face = this.getFace(), - scale = this.size / face.resolution, - offset = 0, - chars = String( text ).split( '' ), - length = chars.length; - - var fontPaths = []; - - for ( i = 0; i < length; i ++ ) { - - var path = new THREE.Path(); - - var ret = this.extractGlyphPoints( chars[ i ], face, scale, offset, path ); - offset += ret.offset; - - fontPaths.push( ret.path ); - - } - - // get the width - - var width = offset / 2; - // - // for ( p = 0; p < allPts.length; p++ ) { - // - // allPts[ p ].x -= width; - // - // } - - //var extract = this.extractPoints( allPts, characterPts ); - //extract.contour = allPts; - - //extract.paths = fontPaths; - //extract.offset = width; - - return { paths : fontPaths, offset : width }; - - }, - - - - - extractGlyphPoints : function( c, face, scale, offset, path ) { - - var pts = []; - - var i, i2, divisions, - outline, action, length, - scaleX, scaleY, - x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, - laste, - glyph = face.glyphs[ c ] || face.glyphs[ '?' ]; - - if ( !glyph ) return; - - if ( glyph.o ) { - - outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) ); - length = outline.length; - - scaleX = scale; - scaleY = scale; - - for ( i = 0; i < length; ) { - - action = outline[ i ++ ]; - - //console.log( action ); - - switch( action ) { - - case 'm': - - // Move To - - x = outline[ i++ ] * scaleX + offset; - y = outline[ i++ ] * scaleY; - - path.moveTo( x, y ); - break; - - case 'l': - - // Line To - - x = outline[ i++ ] * scaleX + offset; - y = outline[ i++ ] * scaleY; - path.lineTo(x,y); - break; - - case 'q': - - // QuadraticCurveTo - - cpx = outline[ i++ ] * scaleX + offset; - cpy = outline[ i++ ] * scaleY; - cpx1 = outline[ i++ ] * scaleX + offset; - cpy1 = outline[ i++ ] * scaleY; - - path.quadraticCurveTo(cpx1, cpy1, cpx, cpy); - - laste = pts[ pts.length - 1 ]; - - if ( laste ) { - - cpx0 = laste.x; - cpy0 = laste.y; - - for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) { - - var t = i2 / divisions; - var tx = THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx ); - var ty = THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy ); - } - - } - - break; - - case 'b': - - // Cubic Bezier Curve - - cpx = outline[ i++ ] * scaleX + offset; - cpy = outline[ i++ ] * scaleY; - cpx1 = outline[ i++ ] * scaleX + offset; - cpy1 = outline[ i++ ] * -scaleY; - cpx2 = outline[ i++ ] * scaleX + offset; - cpy2 = outline[ i++ ] * -scaleY; - - path.bezierCurveTo( cpx, cpy, cpx1, cpy1, cpx2, cpy2 ); - - laste = pts[ pts.length - 1 ]; - - if ( laste ) { - - cpx0 = laste.x; - cpy0 = laste.y; - - for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) { - - var t = i2 / divisions; - var tx = THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx ); - var ty = THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy ); - - } - - } - - break; - - } - - } - } - - - - return { offset: glyph.ha*scale, path:path}; - } - -}; - - -THREE.FontUtils.generateShapes = function( text, parameters ) { - - // Parameters - - parameters = parameters || {}; - - var size = parameters.size !== undefined ? parameters.size : 100; - var curveSegments = parameters.curveSegments !== undefined ? parameters.curveSegments: 4; - - var font = parameters.font !== undefined ? parameters.font : "helvetiker"; - var weight = parameters.weight !== undefined ? parameters.weight : "normal"; - var style = parameters.style !== undefined ? parameters.style : "normal"; - - THREE.FontUtils.size = size; - THREE.FontUtils.divisions = curveSegments; - - THREE.FontUtils.face = font; - THREE.FontUtils.weight = weight; - THREE.FontUtils.style = style; - - // Get a Font data json object - - var data = THREE.FontUtils.drawText( text ); - - var paths = data.paths; - var shapes = []; - - for ( var p = 0, pl = paths.length; p < pl; p ++ ) { - - Array.prototype.push.apply( shapes, paths[ p ].toShapes() ); - - } - - return shapes; - -}; - - -/** - * This code is a quick port of code written in C++ which was submitted to - * flipcode.com by John W. Ratcliff // July 22, 2000 - * See original code and more information here: - * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml - * - * ported to actionscript by Zevan Rosser - * www.actionsnippet.com - * - * ported to javascript by Joshua Koo - * http://www.lab4games.net/zz85/blog - * - */ - - -( function( namespace ) { - - var EPSILON = 0.0000000001; - - // takes in an contour array and returns - - var process = function( contour, indices ) { - - var n = contour.length; - - if ( n < 3 ) return null; - - var result = [], - verts = [], - vertIndices = []; - - /* we want a counter-clockwise polygon in verts */ - - var u, v, w; - - if ( area( contour ) > 0.0 ) { - - for ( v = 0; v < n; v++ ) verts[ v ] = v; - - } else { - - for ( v = 0; v < n; v++ ) verts[ v ] = ( n - 1 ) - v; - - } - - var nv = n; - - /* remove nv - 2 vertices, creating 1 triangle every time */ - - var count = 2 * nv; /* error detection */ - - for( v = nv - 1; nv > 2; ) { - - /* if we loop, it is probably a non-simple polygon */ - - if ( ( count-- ) <= 0 ) { - - //** Triangulate: ERROR - probable bad polygon! - - //throw ( "Warning, unable to triangulate polygon!" ); - //return null; - // Sometimes warning is fine, especially polygons are triangulated in reverse. - console.log( "Warning, unable to triangulate polygon!" ); - - if ( indices ) return vertIndices; - return result; - - } - - /* three consecutive vertices in current polygon, */ - - u = v; if ( nv <= u ) u = 0; /* previous */ - v = u + 1; if ( nv <= v ) v = 0; /* new v */ - w = v + 1; if ( nv <= w ) w = 0; /* next */ - - if ( snip( contour, u, v, w, nv, verts ) ) { - - var a, b, c, s, t; - - /* true names of the vertices */ - - a = verts[ u ]; - b = verts[ v ]; - c = verts[ w ]; - - /* output Triangle */ - - result.push( [ contour[ a ], - contour[ b ], - contour[ c ] ] ); - - - vertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] ); - - /* remove v from the remaining polygon */ - - for( s = v, t = v + 1; t < nv; s++, t++ ) { - - verts[ s ] = verts[ t ]; - - } - - nv--; - - /* reset error detection counter */ - - count = 2 * nv; - - } - - } - - if ( indices ) return vertIndices; - return result; - - }; - - // calculate area of the contour polygon - - var area = function ( contour ) { - - var n = contour.length; - var a = 0.0; - - for( var p = n - 1, q = 0; q < n; p = q++ ) { - - a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y; - - } - - return a * 0.5; - - }; - - var snip = function ( contour, u, v, w, n, verts ) { - - var p; - var ax, ay, bx, by; - var cx, cy, px, py; - - ax = contour[ verts[ u ] ].x; - ay = contour[ verts[ u ] ].y; - - bx = contour[ verts[ v ] ].x; - by = contour[ verts[ v ] ].y; - - cx = contour[ verts[ w ] ].x; - cy = contour[ verts[ w ] ].y; - - if ( EPSILON > (((bx-ax)*(cy-ay)) - ((by-ay)*(cx-ax))) ) return false; - - var aX, aY, bX, bY, cX, cY; - var apx, apy, bpx, bpy, cpx, cpy; - var cCROSSap, bCROSScp, aCROSSbp; - - aX = cx - bx; aY = cy - by; - bX = ax - cx; bY = ay - cy; - cX = bx - ax; cY = by - ay; - - for ( p = 0; p < n; p++ ) { - - px = contour[ verts[ p ] ].x - py = contour[ verts[ p ] ].y - - if ( ( (px === ax) && (py === ay) ) || - ( (px === bx) && (py === by) ) || - ( (px === cx) && (py === cy) ) ) continue; - - apx = px - ax; apy = py - ay; - bpx = px - bx; bpy = py - by; - cpx = px - cx; cpy = py - cy; - - // see if p is inside triangle abc - - aCROSSbp = aX*bpy - aY*bpx; - cCROSSap = cX*apy - cY*apx; - bCROSScp = bX*cpy - bY*cpx; - - if ( (aCROSSbp >= -EPSILON) && (bCROSScp >= -EPSILON) && (cCROSSap >= -EPSILON) ) return false; - - } - - return true; - - }; - - - namespace.Triangulate = process; - namespace.Triangulate.area = area; - - return namespace; - -})(THREE.FontUtils); - -// To use the typeface.js face files, hook up the API -self._typeface_js = { faces: THREE.FontUtils.faces, loadFace: THREE.FontUtils.loadFace }; -THREE.typeface_js = self._typeface_js; - -/** - * @author zz85 / http://www.lab4games.net/zz85/blog - * Extensible curve object - * - * Some common of Curve methods - * .getPoint(t), getTangent(t) - * .getPointAt(u), getTagentAt(u) - * .getPoints(), .getSpacedPoints() - * .getLength() - * .updateArcLengths() - * - * This following classes subclasses THREE.Curve: - * - * -- 2d classes -- - * THREE.LineCurve - * THREE.QuadraticBezierCurve - * THREE.CubicBezierCurve - * THREE.SplineCurve - * THREE.ArcCurve - * THREE.EllipseCurve - * - * -- 3d classes -- - * THREE.LineCurve3 - * THREE.QuadraticBezierCurve3 - * THREE.CubicBezierCurve3 - * THREE.SplineCurve3 - * THREE.ClosedSplineCurve3 - * - * A series of curves can be represented as a THREE.CurvePath - * - **/ - -/************************************************************** - * Abstract Curve base class - **************************************************************/ - -THREE.Curve = function () { - -}; - -// Virtual base class method to overwrite and implement in subclasses -// - t [0 .. 1] - -THREE.Curve.prototype.getPoint = function ( t ) { - - console.log( "Warning, getPoint() not implemented!" ); - return null; - -}; - -// Get point at relative position in curve according to arc length -// - u [0 .. 1] - -THREE.Curve.prototype.getPointAt = function ( u ) { - - var t = this.getUtoTmapping( u ); - return this.getPoint( t ); - -}; - -// Get sequence of points using getPoint( t ) - -THREE.Curve.prototype.getPoints = function ( divisions ) { - - if ( !divisions ) divisions = 5; - - var d, pts = []; - - for ( d = 0; d <= divisions; d ++ ) { - - pts.push( this.getPoint( d / divisions ) ); - - } - - return pts; - -}; - -// Get sequence of points using getPointAt( u ) - -THREE.Curve.prototype.getSpacedPoints = function ( divisions ) { - - if ( !divisions ) divisions = 5; - - var d, pts = []; - - for ( d = 0; d <= divisions; d ++ ) { - - pts.push( this.getPointAt( d / divisions ) ); - - } - - return pts; - -}; - -// Get total curve arc length - -THREE.Curve.prototype.getLength = function () { - - var lengths = this.getLengths(); - return lengths[ lengths.length - 1 ]; - -}; - -// Get list of cumulative segment lengths - -THREE.Curve.prototype.getLengths = function ( divisions ) { - - if ( !divisions ) divisions = (this.__arcLengthDivisions) ? (this.__arcLengthDivisions): 200; - - if ( this.cacheArcLengths - && ( this.cacheArcLengths.length == divisions + 1 ) - && !this.needsUpdate) { - - //console.log( "cached", this.cacheArcLengths ); - return this.cacheArcLengths; - - } - - this.needsUpdate = false; - - var cache = []; - var current, last = this.getPoint( 0 ); - var p, sum = 0; - - cache.push( 0 ); - - for ( p = 1; p <= divisions; p ++ ) { - - current = this.getPoint ( p / divisions ); - sum += current.distanceTo( last ); - cache.push( sum ); - last = current; - - } - - this.cacheArcLengths = cache; - - return cache; // { sums: cache, sum:sum }; Sum is in the last element. - -}; - - -THREE.Curve.prototype.updateArcLengths = function() { - this.needsUpdate = true; - this.getLengths(); -}; - -// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equi distance - -THREE.Curve.prototype.getUtoTmapping = function ( u, distance ) { - - var arcLengths = this.getLengths(); - - var i = 0, il = arcLengths.length; - - var targetArcLength; // The targeted u distance value to get - - if ( distance ) { - - targetArcLength = distance; - - } else { - - targetArcLength = u * arcLengths[ il - 1 ]; - - } - - //var time = Date.now(); - - // binary search for the index with largest value smaller than target u distance - - var low = 0, high = il - 1, comparison; - - while ( low <= high ) { - - i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats - - comparison = arcLengths[ i ] - targetArcLength; - - if ( comparison < 0 ) { - - low = i + 1; - continue; - - } else if ( comparison > 0 ) { - - high = i - 1; - continue; - - } else { - - high = i; - break; - - // DONE - - } - - } - - i = high; - - //console.log('b' , i, low, high, Date.now()- time); - - if ( arcLengths[ i ] == targetArcLength ) { - - var t = i / ( il - 1 ); - return t; - - } - - // we could get finer grain at lengths, or use simple interpolatation between two points - - var lengthBefore = arcLengths[ i ]; - var lengthAfter = arcLengths[ i + 1 ]; - - var segmentLength = lengthAfter - lengthBefore; - - // determine where we are between the 'before' and 'after' points - - var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength; - - // add that fractional amount to t - - var t = ( i + segmentFraction ) / ( il -1 ); - - return t; - -}; - -// Returns a unit vector tangent at t -// In case any sub curve does not implement its tangent derivation, -// 2 points a small delta apart will be used to find its gradient -// which seems to give a reasonable approximation - -THREE.Curve.prototype.getTangent = function( t ) { - - var delta = 0.0001; - var t1 = t - delta; - var t2 = t + delta; - - // Capping in case of danger - - if ( t1 < 0 ) t1 = 0; - if ( t2 > 1 ) t2 = 1; - - var pt1 = this.getPoint( t1 ); - var pt2 = this.getPoint( t2 ); - - var vec = pt2.clone().sub(pt1); - return vec.normalize(); - -}; - - -THREE.Curve.prototype.getTangentAt = function ( u ) { - - var t = this.getUtoTmapping( u ); - return this.getTangent( t ); - -}; - - - - - -/************************************************************** - * Utils - **************************************************************/ - -THREE.Curve.Utils = { - - tangentQuadraticBezier: function ( t, p0, p1, p2 ) { - - return 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 ); - - }, - - // Puay Bing, thanks for helping with this derivative! - - tangentCubicBezier: function (t, p0, p1, p2, p3 ) { - - return -3 * p0 * (1 - t) * (1 - t) + - 3 * p1 * (1 - t) * (1-t) - 6 *t *p1 * (1-t) + - 6 * t * p2 * (1-t) - 3 * t * t * p2 + - 3 * t * t * p3; - }, - - - tangentSpline: function ( t, p0, p1, p2, p3 ) { - - // To check if my formulas are correct - - var h00 = 6 * t * t - 6 * t; // derived from 2t^3 − 3t^2 + 1 - var h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t - var h01 = -6 * t * t + 6 * t; // − 2t3 + 3t2 - var h11 = 3 * t * t - 2 * t; // t3 − t2 - - return h00 + h10 + h01 + h11; - - }, - - // Catmull-Rom - - interpolate: function( p0, p1, p2, p3, t ) { - - var v0 = ( p2 - p0 ) * 0.5; - var v1 = ( p3 - p1 ) * 0.5; - var t2 = t * t; - var t3 = t * t2; - return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1; - - } - -}; - - -// TODO: Transformation for Curves? - -/************************************************************** - * 3D Curves - **************************************************************/ - -// A Factory method for creating new curve subclasses - -THREE.Curve.create = function ( constructor, getPointFunc ) { - - constructor.prototype = Object.create( THREE.Curve.prototype ); - constructor.prototype.getPoint = getPointFunc; - - return constructor; - -}; - -/** - * @author zz85 / http://www.lab4games.net/zz85/blog - * - **/ - -/************************************************************** - * Curved Path - a curve path is simply a array of connected - * curves, but retains the api of a curve - **************************************************************/ - -THREE.CurvePath = function () { - - this.curves = []; - this.bends = []; - - this.autoClose = false; // Automatically closes the path -}; - -THREE.CurvePath.prototype = Object.create( THREE.Curve.prototype ); - -THREE.CurvePath.prototype.add = function ( curve ) { - - this.curves.push( curve ); - -}; - -THREE.CurvePath.prototype.checkConnection = function() { - // TODO - // If the ending of curve is not connected to the starting - // or the next curve, then, this is not a real path -}; - -THREE.CurvePath.prototype.closePath = function() { - // TODO Test - // and verify for vector3 (needs to implement equals) - // Add a line curve if start and end of lines are not connected - var startPoint = this.curves[0].getPoint(0); - var endPoint = this.curves[this.curves.length-1].getPoint(1); - - if (!startPoint.equals(endPoint)) { - this.curves.push( new THREE.LineCurve(endPoint, startPoint) ); - } - -}; - -// To get accurate point with reference to -// entire path distance at time t, -// following has to be done: - -// 1. Length of each sub path have to be known -// 2. Locate and identify type of curve -// 3. Get t for the curve -// 4. Return curve.getPointAt(t') - -THREE.CurvePath.prototype.getPoint = function( t ) { - - var d = t * this.getLength(); - var curveLengths = this.getCurveLengths(); - var i = 0, diff, curve; - - // To think about boundaries points. - - while ( i < curveLengths.length ) { - - if ( curveLengths[ i ] >= d ) { - - diff = curveLengths[ i ] - d; - curve = this.curves[ i ]; - - var u = 1 - diff / curve.getLength(); - - return curve.getPointAt( u ); - - break; - } - - i ++; - - } - - return null; - - // loop where sum != 0, sum > d , sum+1 maxX ) maxX = p.x; - else if ( p.x < minX ) minX = p.x; - - if ( p.y > maxY ) maxY = p.y; - else if ( p.y < minY ) minY = p.y; - - if ( v3 ) { - - if ( p.z > maxZ ) maxZ = p.z; - else if ( p.z < minZ ) minZ = p.z; - - } - - sum.add( p ); - - } - - var ret = { - - minX: minX, - minY: minY, - maxX: maxX, - maxY: maxY - - }; - - if ( v3 ) { - - ret.maxZ = maxZ; - ret.minZ = minZ; - - } - - return ret; - -}; - -/************************************************************** - * Create Geometries Helpers - **************************************************************/ - -/// Generate geometry from path points (for Line or ParticleSystem objects) - -THREE.CurvePath.prototype.createPointsGeometry = function( divisions ) { - - var pts = this.getPoints( divisions, true ); - return this.createGeometry( pts ); - -}; - -// Generate geometry from equidistance sampling along the path - -THREE.CurvePath.prototype.createSpacedPointsGeometry = function( divisions ) { - - var pts = this.getSpacedPoints( divisions, true ); - return this.createGeometry( pts ); - -}; - -THREE.CurvePath.prototype.createGeometry = function( points ) { - - var geometry = new THREE.Geometry(); - - for ( var i = 0; i < points.length; i ++ ) { - - geometry.vertices.push( new THREE.Vector3( points[ i ].x, points[ i ].y, points[ i ].z || 0) ); - - } - - return geometry; - -}; - - -/************************************************************** - * Bend / Wrap Helper Methods - **************************************************************/ - -// Wrap path / Bend modifiers? - -THREE.CurvePath.prototype.addWrapPath = function ( bendpath ) { - - this.bends.push( bendpath ); - -}; - -THREE.CurvePath.prototype.getTransformedPoints = function( segments, bends ) { - - var oldPts = this.getPoints( segments ); // getPoints getSpacedPoints - var i, il; - - if ( !bends ) { - - bends = this.bends; - - } - - for ( i = 0, il = bends.length; i < il; i ++ ) { - - oldPts = this.getWrapPoints( oldPts, bends[ i ] ); - - } - - return oldPts; - -}; - -THREE.CurvePath.prototype.getTransformedSpacedPoints = function( segments, bends ) { - - var oldPts = this.getSpacedPoints( segments ); - - var i, il; - - if ( !bends ) { - - bends = this.bends; - - } - - for ( i = 0, il = bends.length; i < il; i ++ ) { - - oldPts = this.getWrapPoints( oldPts, bends[ i ] ); - - } - - return oldPts; - -}; - -// This returns getPoints() bend/wrapped around the contour of a path. -// Read http://www.planetclegg.com/projects/WarpingTextToSplines.html - -THREE.CurvePath.prototype.getWrapPoints = function ( oldPts, path ) { - - var bounds = this.getBoundingBox(); - - var i, il, p, oldX, oldY, xNorm; - - for ( i = 0, il = oldPts.length; i < il; i ++ ) { - - p = oldPts[ i ]; - - oldX = p.x; - oldY = p.y; - - xNorm = oldX / bounds.maxX; - - // If using actual distance, for length > path, requires line extrusions - //xNorm = path.getUtoTmapping(xNorm, oldX); // 3 styles. 1) wrap stretched. 2) wrap stretch by arc length 3) warp by actual distance - - xNorm = path.getUtoTmapping( xNorm, oldX ); - - // check for out of bounds? - - var pathPt = path.getPoint( xNorm ); - var normal = path.getTangent( xNorm ); - normal.set( -normal.y, normal.x ).multiplyScalar( oldY ); - - p.x = pathPt.x + normal.x; - p.y = pathPt.y + normal.y; - - } - - return oldPts; - -}; - - -/** - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.Gyroscope = function () { - - THREE.Object3D.call( this ); - -}; - -THREE.Gyroscope.prototype = Object.create( THREE.Object3D.prototype ); - -THREE.Gyroscope.prototype.updateMatrixWorld = function ( force ) { - - this.matrixAutoUpdate && this.updateMatrix(); - - // update matrixWorld - - if ( this.matrixWorldNeedsUpdate || force ) { - - if ( this.parent ) { - - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - - this.matrixWorld.decompose( this.translationWorld, this.quaternionWorld, this.scaleWorld ); - this.matrix.decompose( this.translationObject, this.quaternionObject, this.scaleObject ); - - this.matrixWorld.compose( this.translationWorld, this.quaternionObject, this.scaleWorld ); - - - } else { - - this.matrixWorld.copy( this.matrix ); - - } - - - this.matrixWorldNeedsUpdate = false; - - force = true; - - } - - // update children - - for ( var i = 0, l = this.children.length; i < l; i ++ ) { - - this.children[ i ].updateMatrixWorld( force ); - - } - -}; - -THREE.Gyroscope.prototype.translationWorld = new THREE.Vector3(); -THREE.Gyroscope.prototype.translationObject = new THREE.Vector3(); -THREE.Gyroscope.prototype.quaternionWorld = new THREE.Quaternion(); -THREE.Gyroscope.prototype.quaternionObject = new THREE.Quaternion(); -THREE.Gyroscope.prototype.scaleWorld = new THREE.Vector3(); -THREE.Gyroscope.prototype.scaleObject = new THREE.Vector3(); - - -/** - * @author zz85 / http://www.lab4games.net/zz85/blog - * Creates free form 2d path using series of points, lines or curves. - * - **/ - -THREE.Path = function ( points ) { - - THREE.CurvePath.call(this); - - this.actions = []; - - if ( points ) { - - this.fromPoints( points ); - - } - -}; - -THREE.Path.prototype = Object.create( THREE.CurvePath.prototype ); - -THREE.PathActions = { - - MOVE_TO: 'moveTo', - LINE_TO: 'lineTo', - QUADRATIC_CURVE_TO: 'quadraticCurveTo', // Bezier quadratic curve - BEZIER_CURVE_TO: 'bezierCurveTo', // Bezier cubic curve - CSPLINE_THRU: 'splineThru', // Catmull-rom spline - ARC: 'arc', // Circle - ELLIPSE: 'ellipse' -}; - -// TODO Clean up PATH API - -// Create path using straight lines to connect all points -// - vectors: array of Vector2 - -THREE.Path.prototype.fromPoints = function ( vectors ) { - - this.moveTo( vectors[ 0 ].x, vectors[ 0 ].y ); - - for ( var v = 1, vlen = vectors.length; v < vlen; v ++ ) { - - this.lineTo( vectors[ v ].x, vectors[ v ].y ); - - }; - -}; - -// startPath() endPath()? - -THREE.Path.prototype.moveTo = function ( x, y ) { - - var args = Array.prototype.slice.call( arguments ); - this.actions.push( { action: THREE.PathActions.MOVE_TO, args: args } ); - -}; - -THREE.Path.prototype.lineTo = function ( x, y ) { - - var args = Array.prototype.slice.call( arguments ); - - var lastargs = this.actions[ this.actions.length - 1 ].args; - - var x0 = lastargs[ lastargs.length - 2 ]; - var y0 = lastargs[ lastargs.length - 1 ]; - - var curve = new THREE.LineCurve( new THREE.Vector2( x0, y0 ), new THREE.Vector2( x, y ) ); - this.curves.push( curve ); - - this.actions.push( { action: THREE.PathActions.LINE_TO, args: args } ); - -}; - -THREE.Path.prototype.quadraticCurveTo = function( aCPx, aCPy, aX, aY ) { - - var args = Array.prototype.slice.call( arguments ); - - var lastargs = this.actions[ this.actions.length - 1 ].args; - - var x0 = lastargs[ lastargs.length - 2 ]; - var y0 = lastargs[ lastargs.length - 1 ]; - - var curve = new THREE.QuadraticBezierCurve( new THREE.Vector2( x0, y0 ), - new THREE.Vector2( aCPx, aCPy ), - new THREE.Vector2( aX, aY ) ); - this.curves.push( curve ); - - this.actions.push( { action: THREE.PathActions.QUADRATIC_CURVE_TO, args: args } ); - -}; - -THREE.Path.prototype.bezierCurveTo = function( aCP1x, aCP1y, - aCP2x, aCP2y, - aX, aY ) { - - var args = Array.prototype.slice.call( arguments ); - - var lastargs = this.actions[ this.actions.length - 1 ].args; - - var x0 = lastargs[ lastargs.length - 2 ]; - var y0 = lastargs[ lastargs.length - 1 ]; - - var curve = new THREE.CubicBezierCurve( new THREE.Vector2( x0, y0 ), - new THREE.Vector2( aCP1x, aCP1y ), - new THREE.Vector2( aCP2x, aCP2y ), - new THREE.Vector2( aX, aY ) ); - this.curves.push( curve ); - - this.actions.push( { action: THREE.PathActions.BEZIER_CURVE_TO, args: args } ); - -}; - -THREE.Path.prototype.splineThru = function( pts /*Array of Vector*/ ) { - - var args = Array.prototype.slice.call( arguments ); - var lastargs = this.actions[ this.actions.length - 1 ].args; - - var x0 = lastargs[ lastargs.length - 2 ]; - var y0 = lastargs[ lastargs.length - 1 ]; -//--- - var npts = [ new THREE.Vector2( x0, y0 ) ]; - Array.prototype.push.apply( npts, pts ); - - var curve = new THREE.SplineCurve( npts ); - this.curves.push( curve ); - - this.actions.push( { action: THREE.PathActions.CSPLINE_THRU, args: args } ); - -}; - -// FUTURE: Change the API or follow canvas API? - -THREE.Path.prototype.arc = function ( aX, aY, aRadius, - aStartAngle, aEndAngle, aClockwise ) { - - var lastargs = this.actions[ this.actions.length - 1].args; - var x0 = lastargs[ lastargs.length - 2 ]; - var y0 = lastargs[ lastargs.length - 1 ]; - - this.absarc(aX + x0, aY + y0, aRadius, - aStartAngle, aEndAngle, aClockwise ); - - }; - - THREE.Path.prototype.absarc = function ( aX, aY, aRadius, - aStartAngle, aEndAngle, aClockwise ) { - this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); - }; - -THREE.Path.prototype.ellipse = function ( aX, aY, xRadius, yRadius, - aStartAngle, aEndAngle, aClockwise ) { - - var lastargs = this.actions[ this.actions.length - 1].args; - var x0 = lastargs[ lastargs.length - 2 ]; - var y0 = lastargs[ lastargs.length - 1 ]; - - this.absellipse(aX + x0, aY + y0, xRadius, yRadius, - aStartAngle, aEndAngle, aClockwise ); - - }; - - -THREE.Path.prototype.absellipse = function ( aX, aY, xRadius, yRadius, - aStartAngle, aEndAngle, aClockwise ) { - - var args = Array.prototype.slice.call( arguments ); - var curve = new THREE.EllipseCurve( aX, aY, xRadius, yRadius, - aStartAngle, aEndAngle, aClockwise ); - this.curves.push( curve ); - - var lastPoint = curve.getPoint(1); - args.push(lastPoint.x); - args.push(lastPoint.y); - - this.actions.push( { action: THREE.PathActions.ELLIPSE, args: args } ); - - }; - -THREE.Path.prototype.getSpacedPoints = function ( divisions, closedPath ) { - - if ( ! divisions ) divisions = 40; - - var points = []; - - for ( var i = 0; i < divisions; i ++ ) { - - points.push( this.getPoint( i / divisions ) ); - - //if( !this.getPoint( i / divisions ) ) throw "DIE"; - - } - - // if ( closedPath ) { - // - // points.push( points[ 0 ] ); - // - // } - - return points; - -}; - -/* Return an array of vectors based on contour of the path */ - -THREE.Path.prototype.getPoints = function( divisions, closedPath ) { - - if (this.useSpacedPoints) { - console.log('tata'); - return this.getSpacedPoints( divisions, closedPath ); - } - - divisions = divisions || 12; - - var points = []; - - var i, il, item, action, args; - var cpx, cpy, cpx2, cpy2, cpx1, cpy1, cpx0, cpy0, - laste, j, - t, tx, ty; - - for ( i = 0, il = this.actions.length; i < il; i ++ ) { - - item = this.actions[ i ]; - - action = item.action; - args = item.args; - - switch( action ) { - - case THREE.PathActions.MOVE_TO: - - points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) ); - - break; - - case THREE.PathActions.LINE_TO: - - points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) ); - - break; - - case THREE.PathActions.QUADRATIC_CURVE_TO: - - cpx = args[ 2 ]; - cpy = args[ 3 ]; - - cpx1 = args[ 0 ]; - cpy1 = args[ 1 ]; - - if ( points.length > 0 ) { - - laste = points[ points.length - 1 ]; - - cpx0 = laste.x; - cpy0 = laste.y; - - } else { - - laste = this.actions[ i - 1 ].args; - - cpx0 = laste[ laste.length - 2 ]; - cpy0 = laste[ laste.length - 1 ]; - - } - - for ( j = 1; j <= divisions; j ++ ) { - - t = j / divisions; - - tx = THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx ); - ty = THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy ); - - points.push( new THREE.Vector2( tx, ty ) ); - - } - - break; - - case THREE.PathActions.BEZIER_CURVE_TO: - - cpx = args[ 4 ]; - cpy = args[ 5 ]; - - cpx1 = args[ 0 ]; - cpy1 = args[ 1 ]; - - cpx2 = args[ 2 ]; - cpy2 = args[ 3 ]; - - if ( points.length > 0 ) { - - laste = points[ points.length - 1 ]; - - cpx0 = laste.x; - cpy0 = laste.y; - - } else { - - laste = this.actions[ i - 1 ].args; - - cpx0 = laste[ laste.length - 2 ]; - cpy0 = laste[ laste.length - 1 ]; - - } - - - for ( j = 1; j <= divisions; j ++ ) { - - t = j / divisions; - - tx = THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx ); - ty = THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy ); - - points.push( new THREE.Vector2( tx, ty ) ); - - } - - break; - - case THREE.PathActions.CSPLINE_THRU: - - laste = this.actions[ i - 1 ].args; - - var last = new THREE.Vector2( laste[ laste.length - 2 ], laste[ laste.length - 1 ] ); - var spts = [ last ]; - - var n = divisions * args[ 0 ].length; - - spts = spts.concat( args[ 0 ] ); - - var spline = new THREE.SplineCurve( spts ); - - for ( j = 1; j <= n; j ++ ) { - - points.push( spline.getPointAt( j / n ) ) ; - - } - - break; - - case THREE.PathActions.ARC: - - var aX = args[ 0 ], aY = args[ 1 ], - aRadius = args[ 2 ], - aStartAngle = args[ 3 ], aEndAngle = args[ 4 ], - aClockwise = !!args[ 5 ]; - - var deltaAngle = aEndAngle - aStartAngle; - var angle; - var tdivisions = divisions * 2; - - for ( j = 1; j <= tdivisions; j ++ ) { - - t = j / tdivisions; - - if ( ! aClockwise ) { - - t = 1 - t; - - } - - angle = aStartAngle + t * deltaAngle; - - tx = aX + aRadius * Math.cos( angle ); - ty = aY + aRadius * Math.sin( angle ); - - //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty); - - points.push( new THREE.Vector2( tx, ty ) ); - - } - - //console.log(points); - - break; - - case THREE.PathActions.ELLIPSE: - - var aX = args[ 0 ], aY = args[ 1 ], - xRadius = args[ 2 ], - yRadius = args[ 3 ], - aStartAngle = args[ 4 ], aEndAngle = args[ 5 ], - aClockwise = !!args[ 6 ]; - - - var deltaAngle = aEndAngle - aStartAngle; - var angle; - var tdivisions = divisions * 2; - - for ( j = 1; j <= tdivisions; j ++ ) { - - t = j / tdivisions; - - if ( ! aClockwise ) { - - t = 1 - t; - - } - - angle = aStartAngle + t * deltaAngle; - - tx = aX + xRadius * Math.cos( angle ); - ty = aY + yRadius * Math.sin( angle ); - - //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty); - - points.push( new THREE.Vector2( tx, ty ) ); - - } - - //console.log(points); - - break; - - } // end switch - - } - - - - // Normalize to remove the closing point by default. - var lastPoint = points[ points.length - 1]; - var EPSILON = 0.0000000001; - if ( Math.abs(lastPoint.x - points[ 0 ].x) < EPSILON && - Math.abs(lastPoint.y - points[ 0 ].y) < EPSILON) - points.splice( points.length - 1, 1); - if ( closedPath ) { - - points.push( points[ 0 ] ); - - } - - return points; - -}; - -// -// Breaks path into shapes -// -// Assumptions (if parameter isCCW==true the opposite holds): -// - solid shapes are defined clockwise (CW) -// - holes are defined counterclockwise (CCW) -// -// If parameter noHoles==true: -// - all subPaths are regarded as solid shapes -// - definition order CW/CCW has no relevance -// - -THREE.Path.prototype.toShapes = function( isCCW, noHoles ) { - - function extractSubpaths( inActions ) { - - var i, il, item, action, args; - - var subPaths = [], lastPath = new THREE.Path(); - - for ( i = 0, il = inActions.length; i < il; i ++ ) { - - item = inActions[ i ]; - - args = item.args; - action = item.action; - - if ( action == THREE.PathActions.MOVE_TO ) { - - if ( lastPath.actions.length != 0 ) { - - subPaths.push( lastPath ); - lastPath = new THREE.Path(); - - } - - } - - lastPath[ action ].apply( lastPath, args ); - - } - - if ( lastPath.actions.length != 0 ) { - - subPaths.push( lastPath ); - - } - - // console.log(subPaths); - - return subPaths; - } - - function toShapesNoHoles( inSubpaths ) { - - var shapes = []; - - for ( var i = 0, il = inSubpaths.length; i < il; i ++ ) { - - var tmpPath = inSubpaths[ i ]; - - var tmpShape = new THREE.Shape(); - tmpShape.actions = tmpPath.actions; - tmpShape.curves = tmpPath.curves; - - shapes.push( tmpShape ); - } - - //console.log("shape", shapes); - - return shapes; - }; - - function isPointInsidePolygon( inPt, inPolygon ) { - var EPSILON = 0.0000000001; - - var polyLen = inPolygon.length; - - // inPt on polygon contour => immediate success or - // toggling of inside/outside at every single! intersection point of an edge - // with the horizontal line through inPt, left of inPt - // not counting lowerY endpoints of edges and whole edges on that line - var inside = false; - for( var p = polyLen - 1, q = 0; q < polyLen; p = q++ ) { - var edgeLowPt = inPolygon[ p ]; - var edgeHighPt = inPolygon[ q ]; - - var edgeDx = edgeHighPt.x - edgeLowPt.x; - var edgeDy = edgeHighPt.y - edgeLowPt.y; - - if ( Math.abs(edgeDy) > EPSILON ) { // not parallel - if ( edgeDy < 0 ) { - edgeLowPt = inPolygon[ q ]; edgeDx = -edgeDx; - edgeHighPt = inPolygon[ p ]; edgeDy = -edgeDy; - } - if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; - - if ( inPt.y == edgeLowPt.y ) { - if ( inPt.x == edgeLowPt.x ) return true; // inPt is on contour ? - // continue; // no intersection or edgeLowPt => doesn't count !!! - } else { - var perpEdge = edgeDy * (inPt.x - edgeLowPt.x) - edgeDx * (inPt.y - edgeLowPt.y); - if ( perpEdge == 0 ) return true; // inPt is on contour ? - if ( perpEdge < 0 ) continue; - inside = !inside; // true intersection left of inPt - } - } else { // parallel or colinear - if ( inPt.y != edgeLowPt.y ) continue; // parallel - // egde lies on the same horizontal line as inPt - if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) || - ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour ! - // continue; - } - } - - return inside; - } - - - var subPaths = extractSubpaths( this.actions ); - if ( subPaths.length == 0 ) return []; - - if ( noHoles === true ) return toShapesNoHoles( subPaths ); - - - var solid, tmpPath, tmpShape, shapes = []; - - if ( subPaths.length == 1) { - - tmpPath = subPaths[0]; - tmpShape = new THREE.Shape(); - tmpShape.actions = tmpPath.actions; - tmpShape.curves = tmpPath.curves; - shapes.push( tmpShape ); - return shapes; - - } - - var holesFirst = !THREE.Shape.Utils.isClockWise( subPaths[ 0 ].getPoints() ); - holesFirst = isCCW ? !holesFirst : holesFirst; - - // console.log("Holes first", holesFirst); - - var betterShapeHoles = []; - var newShapes = []; - var newShapeHoles = []; - var mainIdx = 0; - var tmpPoints; - - newShapes[mainIdx] = undefined; - newShapeHoles[mainIdx] = []; - - var i, il; - - for ( i = 0, il = subPaths.length; i < il; i ++ ) { - - tmpPath = subPaths[ i ]; - tmpPoints = tmpPath.getPoints(); - solid = THREE.Shape.Utils.isClockWise( tmpPoints ); - solid = isCCW ? !solid : solid; - - if ( solid ) { - - if ( (! holesFirst ) && ( newShapes[mainIdx] ) ) mainIdx++; - - newShapes[mainIdx] = { s: new THREE.Shape(), p: tmpPoints }; - newShapes[mainIdx].s.actions = tmpPath.actions; - newShapes[mainIdx].s.curves = tmpPath.curves; - - if ( holesFirst ) mainIdx++; - newShapeHoles[mainIdx] = []; - - //console.log('cw', i); - - } else { - - newShapeHoles[mainIdx].push( { h: tmpPath, p: tmpPoints[0] } ); - - //console.log('ccw', i); - - } - - } - - // only Holes? -> probably all Shapes with wrong orientation - if ( !newShapes[0] ) return toShapesNoHoles( subPaths ); - - - if ( newShapes.length > 1 ) { - var ambigious = false; - var toChange = []; - - for (var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++ ) { - betterShapeHoles[sIdx] = []; - } - for (var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++ ) { - var sh = newShapes[sIdx]; - var sho = newShapeHoles[sIdx]; - for (var hIdx = 0; hIdx < sho.length; hIdx++ ) { - var ho = sho[hIdx]; - var hole_unassigned = true; - for (var s2Idx = 0; s2Idx < newShapes.length; s2Idx++ ) { - if ( isPointInsidePolygon( ho.p, newShapes[s2Idx].p ) ) { - if ( sIdx != s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } ); - if ( hole_unassigned ) { - hole_unassigned = false; - betterShapeHoles[s2Idx].push( ho ); - } else { - ambigious = true; - } - } - } - if ( hole_unassigned ) { betterShapeHoles[sIdx].push( ho ); } - } - } - // console.log("ambigious: ", ambigious); - if ( toChange.length > 0 ) { - // console.log("to change: ", toChange); - if (! ambigious) newShapeHoles = betterShapeHoles; - } - } - - var tmpHoles, j, jl; - for ( i = 0, il = newShapes.length; i < il; i ++ ) { - tmpShape = newShapes[i].s; - shapes.push( tmpShape ); - tmpHoles = newShapeHoles[i]; - for ( j = 0, jl = tmpHoles.length; j < jl; j ++ ) { - tmpShape.holes.push( tmpHoles[j].h ); - } - } - - //console.log("shape", shapes); - - return shapes; - -}; - -/** - * @author zz85 / http://www.lab4games.net/zz85/blog - * Defines a 2d shape plane using paths. - **/ - -// STEP 1 Create a path. -// STEP 2 Turn path into shape. -// STEP 3 ExtrudeGeometry takes in Shape/Shapes -// STEP 3a - Extract points from each shape, turn to vertices -// STEP 3b - Triangulate each shape, add faces. - -THREE.Shape = function () { - - THREE.Path.apply( this, arguments ); - this.holes = []; - -}; - -THREE.Shape.prototype = Object.create( THREE.Path.prototype ); - -// Convenience method to return ExtrudeGeometry - -THREE.Shape.prototype.extrude = function ( options ) { - - var extruded = new THREE.ExtrudeGeometry( this, options ); - return extruded; - -}; - -// Convenience method to return ShapeGeometry - -THREE.Shape.prototype.makeGeometry = function ( options ) { - - var geometry = new THREE.ShapeGeometry( this, options ); - return geometry; - -}; - -// Get points of holes - -THREE.Shape.prototype.getPointsHoles = function ( divisions ) { - - var i, il = this.holes.length, holesPts = []; - - for ( i = 0; i < il; i ++ ) { - - holesPts[ i ] = this.holes[ i ].getTransformedPoints( divisions, this.bends ); - - } - - return holesPts; - -}; - -// Get points of holes (spaced by regular distance) - -THREE.Shape.prototype.getSpacedPointsHoles = function ( divisions ) { - - var i, il = this.holes.length, holesPts = []; - - for ( i = 0; i < il; i ++ ) { - - holesPts[ i ] = this.holes[ i ].getTransformedSpacedPoints( divisions, this.bends ); - - } - - return holesPts; - -}; - - -// Get points of shape and holes (keypoints based on segments parameter) - -THREE.Shape.prototype.extractAllPoints = function ( divisions ) { - - return { - - shape: this.getTransformedPoints( divisions ), - holes: this.getPointsHoles( divisions ) - - }; - -}; - -THREE.Shape.prototype.extractPoints = function ( divisions ) { - - if (this.useSpacedPoints) { - return this.extractAllSpacedPoints(divisions); - } - - return this.extractAllPoints(divisions); - -}; - -// -// THREE.Shape.prototype.extractAllPointsWithBend = function ( divisions, bend ) { -// -// return { -// -// shape: this.transform( bend, divisions ), -// holes: this.getPointsHoles( divisions, bend ) -// -// }; -// -// }; - -// Get points of shape and holes (spaced by regular distance) - -THREE.Shape.prototype.extractAllSpacedPoints = function ( divisions ) { - - return { - - shape: this.getTransformedSpacedPoints( divisions ), - holes: this.getSpacedPointsHoles( divisions ) - - }; - -}; - -/************************************************************** - * Utils - **************************************************************/ - -THREE.Shape.Utils = { - - triangulateShape: function ( contour, holes ) { - - function point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) { - // inOtherPt needs to be colinear to the inSegment - if ( inSegPt1.x != inSegPt2.x ) { - if ( inSegPt1.x < inSegPt2.x ) { - return ( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) ); - } else { - return ( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) ); - } - } else { - if ( inSegPt1.y < inSegPt2.y ) { - return ( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) ); - } else { - return ( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) ); - } - } - } - - function intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) { - var EPSILON = 0.0000000001; - - var seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y; - var seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y; - - var seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x; - var seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y; - - var limit = seg1dy * seg2dx - seg1dx * seg2dy; - var perpSeg1 = seg1dy * seg1seg2dx - seg1dx * seg1seg2dy; - - if ( Math.abs(limit) > EPSILON ) { // not parallel - - var perpSeg2; - if ( limit > 0 ) { - if ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) return []; - perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy; - if ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) return []; - } else { - if ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) return []; - perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy; - if ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) return []; - } - - // i.e. to reduce rounding errors - // intersection at endpoint of segment#1? - if ( perpSeg2 == 0 ) { - if ( ( inExcludeAdjacentSegs ) && - ( ( perpSeg1 == 0 ) || ( perpSeg1 == limit ) ) ) return []; - return [ inSeg1Pt1 ]; - } - if ( perpSeg2 == limit ) { - if ( ( inExcludeAdjacentSegs ) && - ( ( perpSeg1 == 0 ) || ( perpSeg1 == limit ) ) ) return []; - return [ inSeg1Pt2 ]; - } - // intersection at endpoint of segment#2? - if ( perpSeg1 == 0 ) return [ inSeg2Pt1 ]; - if ( perpSeg1 == limit ) return [ inSeg2Pt2 ]; - - // return real intersection point - var factorSeg1 = perpSeg2 / limit; - return [ { x: inSeg1Pt1.x + factorSeg1 * seg1dx, - y: inSeg1Pt1.y + factorSeg1 * seg1dy } ]; - - } else { // parallel or colinear - if ( ( perpSeg1 != 0 ) || - ( seg2dy * seg1seg2dx != seg2dx * seg1seg2dy ) ) return []; - - // they are collinear or degenerate - var seg1Pt = ( (seg1dx == 0) && (seg1dy == 0) ); // segment1 ist just a point? - var seg2Pt = ( (seg2dx == 0) && (seg2dy == 0) ); // segment2 ist just a point? - // both segments are points - if ( seg1Pt && seg2Pt ) { - if ( (inSeg1Pt1.x != inSeg2Pt1.x) || - (inSeg1Pt1.y != inSeg2Pt1.y) ) return []; // they are distinct points - return [ inSeg1Pt1 ]; // they are the same point - } - // segment#1 is a single point - if ( seg1Pt ) { - if (! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) ) return []; // but not in segment#2 - return [ inSeg1Pt1 ]; - } - // segment#2 is a single point - if ( seg2Pt ) { - if (! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) ) return []; // but not in segment#1 - return [ inSeg2Pt1 ]; - } - - // they are collinear segments, which might overlap - var seg1min, seg1max, seg1minVal, seg1maxVal; - var seg2min, seg2max, seg2minVal, seg2maxVal; - if (seg1dx != 0) { // the segments are NOT on a vertical line - if ( inSeg1Pt1.x < inSeg1Pt2.x ) { - seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x; - seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x; - } else { - seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x; - seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x; - } - if ( inSeg2Pt1.x < inSeg2Pt2.x ) { - seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x; - seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x; - } else { - seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x; - seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x; - } - } else { // the segments are on a vertical line - if ( inSeg1Pt1.y < inSeg1Pt2.y ) { - seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y; - seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y; - } else { - seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y; - seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y; - } - if ( inSeg2Pt1.y < inSeg2Pt2.y ) { - seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y; - seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y; - } else { - seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y; - seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y; - } - } - if ( seg1minVal <= seg2minVal ) { - if ( seg1maxVal < seg2minVal ) return []; - if ( seg1maxVal == seg2minVal ) { - if ( inExcludeAdjacentSegs ) return []; - return [ seg2min ]; - } - if ( seg1maxVal <= seg2maxVal ) return [ seg2min, seg1max ]; - return [ seg2min, seg2max ]; - } else { - if ( seg1minVal > seg2maxVal ) return []; - if ( seg1minVal == seg2maxVal ) { - if ( inExcludeAdjacentSegs ) return []; - return [ seg1min ]; - } - if ( seg1maxVal <= seg2maxVal ) return [ seg1min, seg1max ]; - return [ seg1min, seg2max ]; - } - } - } - - function isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) { - // The order of legs is important - - var EPSILON = 0.0000000001; - - // translation of all points, so that Vertex is at (0,0) - var legFromPtX = inLegFromPt.x - inVertex.x, legFromPtY = inLegFromPt.y - inVertex.y; - var legToPtX = inLegToPt.x - inVertex.x, legToPtY = inLegToPt.y - inVertex.y; - var otherPtX = inOtherPt.x - inVertex.x, otherPtY = inOtherPt.y - inVertex.y; - - // main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg. - var from2toAngle = legFromPtX * legToPtY - legFromPtY * legToPtX; - var from2otherAngle = legFromPtX * otherPtY - legFromPtY * otherPtX; - - if ( Math.abs(from2toAngle) > EPSILON ) { // angle != 180 deg. - - var other2toAngle = otherPtX * legToPtY - otherPtY * legToPtX; - // console.log( "from2to: " + from2toAngle + ", from2other: " + from2otherAngle + ", other2to: " + other2toAngle ); - - if ( from2toAngle > 0 ) { // main angle < 180 deg. - return ( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) ); - } else { // main angle > 180 deg. - return ( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) ); - } - } else { // angle == 180 deg. - // console.log( "from2to: 180 deg., from2other: " + from2otherAngle ); - return ( from2otherAngle > 0 ); - } - } - - - function removeHoles( contour, holes ) { - - var shape = contour.concat(); // work on this shape - var hole; - - function isCutLineInsideAngles( inShapeIdx, inHoleIdx ) { - // Check if hole point lies within angle around shape point - var lastShapeIdx = shape.length - 1; - - var prevShapeIdx = inShapeIdx - 1; - if ( prevShapeIdx < 0 ) prevShapeIdx = lastShapeIdx; - - var nextShapeIdx = inShapeIdx + 1; - if ( nextShapeIdx > lastShapeIdx ) nextShapeIdx = 0; - - var insideAngle = isPointInsideAngle( shape[inShapeIdx], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[inHoleIdx] ); - if (! insideAngle ) { - // console.log( "Vertex (Shape): " + inShapeIdx + ", Point: " + hole[inHoleIdx].x + "/" + hole[inHoleIdx].y ); - return false; - } - - // Check if shape point lies within angle around hole point - var lastHoleIdx = hole.length - 1; - - var prevHoleIdx = inHoleIdx - 1; - if ( prevHoleIdx < 0 ) prevHoleIdx = lastHoleIdx; - - var nextHoleIdx = inHoleIdx + 1; - if ( nextHoleIdx > lastHoleIdx ) nextHoleIdx = 0; - - insideAngle = isPointInsideAngle( hole[inHoleIdx], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[inShapeIdx] ); - if (! insideAngle ) { - // console.log( "Vertex (Hole): " + inHoleIdx + ", Point: " + shape[inShapeIdx].x + "/" + shape[inShapeIdx].y ); - return false; - } - - return true; - } - - function intersectsShapeEdge( inShapePt, inHolePt ) { - // checks for intersections with shape edges - var sIdx, nextIdx, intersection; - for ( sIdx = 0; sIdx < shape.length; sIdx++ ) { - nextIdx = sIdx+1; nextIdx %= shape.length; - intersection = intersect_segments_2D( inShapePt, inHolePt, shape[sIdx], shape[nextIdx], true ); - if ( intersection.length > 0 ) return true; - } - - return false; - } - - var indepHoles = []; - - function intersectsHoleEdge( inShapePt, inHolePt ) { - // checks for intersections with hole edges - var ihIdx, chkHole, - hIdx, nextIdx, intersection; - for ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx++ ) { - chkHole = holes[indepHoles[ihIdx]]; - for ( hIdx = 0; hIdx < chkHole.length; hIdx++ ) { - nextIdx = hIdx+1; nextIdx %= chkHole.length; - intersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[hIdx], chkHole[nextIdx], true ); - if ( intersection.length > 0 ) return true; - } - } - return false; - } - - var holeIndex, shapeIndex, - shapePt, holePt, - holeIdx, cutKey, failedCuts = [], - tmpShape1, tmpShape2, - tmpHole1, tmpHole2; - - for ( var h = 0, hl = holes.length; h < hl; h ++ ) { - - indepHoles.push( h ); - - } - - var minShapeIndex = 0; - var counter = indepHoles.length * 2; - while ( indepHoles.length > 0 ) { - counter --; - if ( counter < 0 ) { - console.log( "Infinite Loop! Holes left:" + indepHoles.length + ", Probably Hole outside Shape!" ); - break; - } - - // search for shape-vertex and hole-vertex, - // which can be connected without intersections - for ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex++ ) { - - shapePt = shape[ shapeIndex ]; - holeIndex = -1; - - // search for hole which can be reached without intersections - for ( var h = 0; h < indepHoles.length; h ++ ) { - holeIdx = indepHoles[h]; - - // prevent multiple checks - cutKey = shapePt.x + ":" + shapePt.y + ":" + holeIdx; - if ( failedCuts[cutKey] !== undefined ) continue; - - hole = holes[holeIdx]; - for ( var h2 = 0; h2 < hole.length; h2 ++ ) { - holePt = hole[ h2 ]; - if (! isCutLineInsideAngles( shapeIndex, h2 ) ) continue; - if ( intersectsShapeEdge( shapePt, holePt ) ) continue; - if ( intersectsHoleEdge( shapePt, holePt ) ) continue; - - holeIndex = h2; - indepHoles.splice(h,1); - - tmpShape1 = shape.slice( 0, shapeIndex+1 ); - tmpShape2 = shape.slice( shapeIndex ); - tmpHole1 = hole.slice( holeIndex ); - tmpHole2 = hole.slice( 0, holeIndex+1 ); - - shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 ); - - minShapeIndex = shapeIndex; - - // Debug only, to show the selected cuts - // glob_CutLines.push( [ shapePt, holePt ] ); - - break; - } - if ( holeIndex >= 0 ) break; // hole-vertex found - - failedCuts[cutKey] = true; // remember failure - } - if ( holeIndex >= 0 ) break; // hole-vertex found - } - } - - return shape; /* shape with no holes */ - } - - - var i, il, f, face, - key, index, - allPointsMap = {}; - - // To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first. - - var allpoints = contour.concat(); - - for ( var h = 0, hl = holes.length; h < hl; h ++ ) { - - Array.prototype.push.apply( allpoints, holes[h] ); - - } - - //console.log( "allpoints",allpoints, allpoints.length ); - - // prepare all points map - - for ( i = 0, il = allpoints.length; i < il; i ++ ) { - - key = allpoints[ i ].x + ":" + allpoints[ i ].y; - - if ( allPointsMap[ key ] !== undefined ) { - - console.log( "Duplicate point", key ); - - } - - allPointsMap[ key ] = i; - - } - - // remove holes by cutting paths to holes and adding them to the shape - var shapeWithoutHoles = removeHoles( contour, holes ); - - var triangles = THREE.FontUtils.Triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape - //console.log( "triangles",triangles, triangles.length ); - - // check all face vertices against all points map - - for ( i = 0, il = triangles.length; i < il; i ++ ) { - - face = triangles[ i ]; - - for ( f = 0; f < 3; f ++ ) { - - key = face[ f ].x + ":" + face[ f ].y; - - index = allPointsMap[ key ]; - - if ( index !== undefined ) { - - face[ f ] = index; - - } - - } - - } - - return triangles.concat(); - - }, - - isClockWise: function ( pts ) { - - return THREE.FontUtils.Triangulate.area( pts ) < 0; - - }, - - // Bezier Curves formulas obtained from - // http://en.wikipedia.org/wiki/B%C3%A9zier_curve - - // Quad Bezier Functions - - b2p0: function ( t, p ) { - - var k = 1 - t; - return k * k * p; - - }, - - b2p1: function ( t, p ) { - - return 2 * ( 1 - t ) * t * p; - - }, - - b2p2: function ( t, p ) { - - return t * t * p; - - }, - - b2: function ( t, p0, p1, p2 ) { - - return this.b2p0( t, p0 ) + this.b2p1( t, p1 ) + this.b2p2( t, p2 ); - - }, - - // Cubic Bezier Functions - - b3p0: function ( t, p ) { - - var k = 1 - t; - return k * k * k * p; - - }, - - b3p1: function ( t, p ) { - - var k = 1 - t; - return 3 * k * k * t * p; - - }, - - b3p2: function ( t, p ) { - - var k = 1 - t; - return 3 * k * t * t * p; - - }, - - b3p3: function ( t, p ) { - - return t * t * t * p; - - }, - - b3: function ( t, p0, p1, p2, p3 ) { - - return this.b3p0( t, p0 ) + this.b3p1( t, p1 ) + this.b3p2( t, p2 ) + this.b3p3( t, p3 ); - - } - -}; - - -/************************************************************** - * Line - **************************************************************/ - -THREE.LineCurve = function ( v1, v2 ) { - - this.v1 = v1; - this.v2 = v2; - -}; - -THREE.LineCurve.prototype = Object.create( THREE.Curve.prototype ); - -THREE.LineCurve.prototype.getPoint = function ( t ) { - - var point = this.v2.clone().sub(this.v1); - point.multiplyScalar( t ).add( this.v1 ); - - return point; - -}; - -// Line curve is linear, so we can overwrite default getPointAt - -THREE.LineCurve.prototype.getPointAt = function ( u ) { - - return this.getPoint( u ); - -}; - -THREE.LineCurve.prototype.getTangent = function( t ) { - - var tangent = this.v2.clone().sub(this.v1); - - return tangent.normalize(); - -}; -/************************************************************** - * Quadratic Bezier curve - **************************************************************/ - - -THREE.QuadraticBezierCurve = function ( v0, v1, v2 ) { - - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - -}; - -THREE.QuadraticBezierCurve.prototype = Object.create( THREE.Curve.prototype ); - - -THREE.QuadraticBezierCurve.prototype.getPoint = function ( t ) { - - var tx, ty; - - tx = THREE.Shape.Utils.b2( t, this.v0.x, this.v1.x, this.v2.x ); - ty = THREE.Shape.Utils.b2( t, this.v0.y, this.v1.y, this.v2.y ); - - return new THREE.Vector2( tx, ty ); - -}; - - -THREE.QuadraticBezierCurve.prototype.getTangent = function( t ) { - - var tx, ty; - - tx = THREE.Curve.Utils.tangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x ); - ty = THREE.Curve.Utils.tangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y ); - - // returns unit vector - - var tangent = new THREE.Vector2( tx, ty ); - tangent.normalize(); - - return tangent; - -}; -/************************************************************** - * Cubic Bezier curve - **************************************************************/ - -THREE.CubicBezierCurve = function ( v0, v1, v2, v3 ) { - - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - this.v3 = v3; - -}; - -THREE.CubicBezierCurve.prototype = Object.create( THREE.Curve.prototype ); - -THREE.CubicBezierCurve.prototype.getPoint = function ( t ) { - - var tx, ty; - - tx = THREE.Shape.Utils.b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ); - ty = THREE.Shape.Utils.b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ); - - return new THREE.Vector2( tx, ty ); - -}; - -THREE.CubicBezierCurve.prototype.getTangent = function( t ) { - - var tx, ty; - - tx = THREE.Curve.Utils.tangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ); - ty = THREE.Curve.Utils.tangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ); - - var tangent = new THREE.Vector2( tx, ty ); - tangent.normalize(); - - return tangent; - -}; -/************************************************************** - * Spline curve - **************************************************************/ - -THREE.SplineCurve = function ( points /* array of Vector2 */ ) { - - this.points = (points == undefined) ? [] : points; - -}; - -THREE.SplineCurve.prototype = Object.create( THREE.Curve.prototype ); - -THREE.SplineCurve.prototype.getPoint = function ( t ) { - - var v = new THREE.Vector2(); - var c = []; - var points = this.points, point, intPoint, weight; - point = ( points.length - 1 ) * t; - - intPoint = Math.floor( point ); - weight = point - intPoint; - - c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1; - c[ 1 ] = intPoint; - c[ 2 ] = intPoint > points.length - 2 ? points.length -1 : intPoint + 1; - c[ 3 ] = intPoint > points.length - 3 ? points.length -1 : intPoint + 2; - - v.x = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].x, points[ c[ 1 ] ].x, points[ c[ 2 ] ].x, points[ c[ 3 ] ].x, weight ); - v.y = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].y, points[ c[ 1 ] ].y, points[ c[ 2 ] ].y, points[ c[ 3 ] ].y, weight ); - - return v; - -}; -/************************************************************** - * Ellipse curve - **************************************************************/ - -THREE.EllipseCurve = function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise ) { - - this.aX = aX; - this.aY = aY; - - this.xRadius = xRadius; - this.yRadius = yRadius; - - this.aStartAngle = aStartAngle; - this.aEndAngle = aEndAngle; - - this.aClockwise = aClockwise; - -}; - -THREE.EllipseCurve.prototype = Object.create( THREE.Curve.prototype ); - -THREE.EllipseCurve.prototype.getPoint = function ( t ) { - - var angle; - var deltaAngle = this.aEndAngle - this.aStartAngle; - - if ( deltaAngle < 0 ) deltaAngle += Math.PI * 2; - if ( deltaAngle > Math.PI * 2 ) deltaAngle -= Math.PI * 2; - - if ( this.aClockwise === true ) { - - angle = this.aEndAngle + ( 1 - t ) * ( Math.PI * 2 - deltaAngle ); - - } else { - - angle = this.aStartAngle + t * deltaAngle; - - } - - var tx = this.aX + this.xRadius * Math.cos( angle ); - var ty = this.aY + this.yRadius * Math.sin( angle ); - - return new THREE.Vector2( tx, ty ); - -}; - -/************************************************************** - * Arc curve - **************************************************************/ - -THREE.ArcCurve = function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { - - THREE.EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); -}; - -THREE.ArcCurve.prototype = Object.create( THREE.EllipseCurve.prototype ); -/************************************************************** - * Line3D - **************************************************************/ - -THREE.LineCurve3 = THREE.Curve.create( - - function ( v1, v2 ) { - - this.v1 = v1; - this.v2 = v2; - - }, - - function ( t ) { - - var r = new THREE.Vector3(); - - - r.subVectors( this.v2, this.v1 ); // diff - r.multiplyScalar( t ); - r.add( this.v1 ); - - return r; - - } - -); - -/************************************************************** - * Quadratic Bezier 3D curve - **************************************************************/ - -THREE.QuadraticBezierCurve3 = THREE.Curve.create( - - function ( v0, v1, v2 ) { - - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - - }, - - function ( t ) { - - var tx, ty, tz; - - tx = THREE.Shape.Utils.b2( t, this.v0.x, this.v1.x, this.v2.x ); - ty = THREE.Shape.Utils.b2( t, this.v0.y, this.v1.y, this.v2.y ); - tz = THREE.Shape.Utils.b2( t, this.v0.z, this.v1.z, this.v2.z ); - - return new THREE.Vector3( tx, ty, tz ); - - } - -); -/************************************************************** - * Cubic Bezier 3D curve - **************************************************************/ - -THREE.CubicBezierCurve3 = THREE.Curve.create( - - function ( v0, v1, v2, v3 ) { - - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - this.v3 = v3; - - }, - - function ( t ) { - - var tx, ty, tz; - - tx = THREE.Shape.Utils.b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ); - ty = THREE.Shape.Utils.b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ); - tz = THREE.Shape.Utils.b3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z ); - - return new THREE.Vector3( tx, ty, tz ); - - } - -); -/************************************************************** - * Spline 3D curve - **************************************************************/ - - -THREE.SplineCurve3 = THREE.Curve.create( - - function ( points /* array of Vector3 */) { - - this.points = (points == undefined) ? [] : points; - - }, - - function ( t ) { - - var v = new THREE.Vector3(); - var c = []; - var points = this.points, point, intPoint, weight; - point = ( points.length - 1 ) * t; - - intPoint = Math.floor( point ); - weight = point - intPoint; - - c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1; - c[ 1 ] = intPoint; - c[ 2 ] = intPoint > points.length - 2 ? points.length - 1 : intPoint + 1; - c[ 3 ] = intPoint > points.length - 3 ? points.length - 1 : intPoint + 2; - - var pt0 = points[ c[0] ], - pt1 = points[ c[1] ], - pt2 = points[ c[2] ], - pt3 = points[ c[3] ]; - - v.x = THREE.Curve.Utils.interpolate(pt0.x, pt1.x, pt2.x, pt3.x, weight); - v.y = THREE.Curve.Utils.interpolate(pt0.y, pt1.y, pt2.y, pt3.y, weight); - v.z = THREE.Curve.Utils.interpolate(pt0.z, pt1.z, pt2.z, pt3.z, weight); - - return v; - - } - -); - - -// THREE.SplineCurve3.prototype.getTangent = function(t) { -// var v = new THREE.Vector3(); -// var c = []; -// var points = this.points, point, intPoint, weight; -// point = ( points.length - 1 ) * t; - -// intPoint = Math.floor( point ); -// weight = point - intPoint; - -// c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1; -// c[ 1 ] = intPoint; -// c[ 2 ] = intPoint > points.length - 2 ? points.length - 1 : intPoint + 1; -// c[ 3 ] = intPoint > points.length - 3 ? points.length - 1 : intPoint + 2; - -// var pt0 = points[ c[0] ], -// pt1 = points[ c[1] ], -// pt2 = points[ c[2] ], -// pt3 = points[ c[3] ]; - -// // t = weight; -// v.x = THREE.Curve.Utils.tangentSpline( t, pt0.x, pt1.x, pt2.x, pt3.x ); -// v.y = THREE.Curve.Utils.tangentSpline( t, pt0.y, pt1.y, pt2.y, pt3.y ); -// v.z = THREE.Curve.Utils.tangentSpline( t, pt0.z, pt1.z, pt2.z, pt3.z ); - -// return v; - -// } -/************************************************************** - * Closed Spline 3D curve - **************************************************************/ - - -THREE.ClosedSplineCurve3 = THREE.Curve.create( - - function ( points /* array of Vector3 */) { - - this.points = (points == undefined) ? [] : points; - - }, - - function ( t ) { - - var v = new THREE.Vector3(); - var c = []; - var points = this.points, point, intPoint, weight; - point = ( points.length - 0 ) * t; - // This needs to be from 0-length +1 - - intPoint = Math.floor( point ); - weight = point - intPoint; - - intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length; - c[ 0 ] = ( intPoint - 1 ) % points.length; - c[ 1 ] = ( intPoint ) % points.length; - c[ 2 ] = ( intPoint + 1 ) % points.length; - c[ 3 ] = ( intPoint + 2 ) % points.length; - - v.x = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].x, points[ c[ 1 ] ].x, points[ c[ 2 ] ].x, points[ c[ 3 ] ].x, weight ); - v.y = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].y, points[ c[ 1 ] ].y, points[ c[ 2 ] ].y, points[ c[ 3 ] ].y, weight ); - v.z = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].z, points[ c[ 1 ] ].z, points[ c[ 2 ] ].z, points[ c[ 3 ] ].z, weight ); - - return v; - - } - -); -/** - * @author mikael emtinger / http://gomo.se/ - */ - -THREE.AnimationHandler = ( function () { - - var playing = []; - var library = {}; - var that = {}; - - that.update = function ( deltaTimeMS ) { - - for ( var i = 0; i < playing.length; i ++ ) { - - playing[ i ].update( deltaTimeMS ); - - } - - }; - - that.addToUpdate = function ( animation ) { - - if ( playing.indexOf( animation ) === -1 ) { - - playing.push( animation ); - - } - - }; - - that.removeFromUpdate = function ( animation ) { - - var index = playing.indexOf( animation ); - - if ( index !== -1 ) { - - playing.splice( index, 1 ); - - } - - }; - - that.add = function ( data ) { - - if ( library[ data.name ] !== undefined ) { - - console.log( "THREE.AnimationHandler.add: Warning! " + data.name + " already exists in library. Overwriting." ); - - } - - library[ data.name ] = data; - initData( data ); - - }; - - that.remove = function ( name ) { - - if ( library[ name ] === undefined ) { - - console.log( "THREE.AnimationHandler.add: Warning! " + name + " doesn't exists in library. Doing nothing." ); - - } - - library[ name ] = undefined; - - }; - - that.get = function ( name ) { - - if ( typeof name === "string" ) { - - if ( library[ name ] ) { - - return library[ name ]; - - } else { - - return null; - - } - - } else { - - // todo: add simple tween library - - } - - }; - - that.parse = function ( root ) { - - // setup hierarchy - - var hierarchy = []; - - if ( root instanceof THREE.SkinnedMesh ) { - - for ( var b = 0; b < root.skeleton.bones.length; b++ ) { - - hierarchy.push( root.skeleton.bones[ b ] ); - - } - - } else { - - parseRecurseHierarchy( root, hierarchy ); - - } - - return hierarchy; - - }; - - var parseRecurseHierarchy = function ( root, hierarchy ) { - - hierarchy.push( root ); - - for ( var c = 0; c < root.children.length; c++ ) - parseRecurseHierarchy( root.children[ c ], hierarchy ); - - } - - var initData = function ( data ) { - - if ( data.initialized === true ) - return; - - - // loop through all keys - - for ( var h = 0; h < data.hierarchy.length; h ++ ) { - - for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) { - - // remove minus times - - if ( data.hierarchy[ h ].keys[ k ].time < 0 ) { - - data.hierarchy[ h ].keys[ k ].time = 0; - - } - - // create quaternions - - if ( data.hierarchy[ h ].keys[ k ].rot !== undefined && - !( data.hierarchy[ h ].keys[ k ].rot instanceof THREE.Quaternion ) ) { - - var quat = data.hierarchy[ h ].keys[ k ].rot; - data.hierarchy[ h ].keys[ k ].rot = new THREE.Quaternion().fromArray( quat ); - - } - - } - - // prepare morph target keys - - if ( data.hierarchy[ h ].keys.length && data.hierarchy[ h ].keys[ 0 ].morphTargets !== undefined ) { - - // get all used - - var usedMorphTargets = {}; - - for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) { - - for ( var m = 0; m < data.hierarchy[ h ].keys[ k ].morphTargets.length; m ++ ) { - - var morphTargetName = data.hierarchy[ h ].keys[ k ].morphTargets[ m ]; - usedMorphTargets[ morphTargetName ] = -1; - - } - - } - - data.hierarchy[ h ].usedMorphTargets = usedMorphTargets; - - - // set all used on all frames - - for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) { - - var influences = {}; - - for ( var morphTargetName in usedMorphTargets ) { - - for ( var m = 0; m < data.hierarchy[ h ].keys[ k ].morphTargets.length; m ++ ) { - - if ( data.hierarchy[ h ].keys[ k ].morphTargets[ m ] === morphTargetName ) { - - influences[ morphTargetName ] = data.hierarchy[ h ].keys[ k ].morphTargetsInfluences[ m ]; - break; - - } - - } - - if ( m === data.hierarchy[ h ].keys[ k ].morphTargets.length ) { - - influences[ morphTargetName ] = 0; - - } - - } - - data.hierarchy[ h ].keys[ k ].morphTargetsInfluences = influences; - - } - - } - - - // remove all keys that are on the same time - - for ( var k = 1; k < data.hierarchy[ h ].keys.length; k ++ ) { - - if ( data.hierarchy[ h ].keys[ k ].time === data.hierarchy[ h ].keys[ k - 1 ].time ) { - - data.hierarchy[ h ].keys.splice( k, 1 ); - k --; - - } - - } - - - // set index - - for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) { - - data.hierarchy[ h ].keys[ k ].index = k; - - } - - } - - data.initialized = true; - - }; - - - // interpolation types - - that.LINEAR = 0; - that.CATMULLROM = 1; - that.CATMULLROM_FORWARD = 2; - - return that; - -}() ); - -/** - * @author mikael emtinger / http://gomo.se/ - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.Animation = function ( root, name ) { - - this.root = root; - this.data = THREE.AnimationHandler.get( name ); - this.hierarchy = THREE.AnimationHandler.parse( root ); - - this.currentTime = 0; - this.timeScale = 1; - - this.isPlaying = false; - this.isPaused = true; - this.loop = true; - this.weight = 0; - - this.interpolationType = THREE.AnimationHandler.LINEAR; - -}; - - -THREE.Animation.prototype.keyTypes = [ "pos", "rot", "scl" ]; - - -THREE.Animation.prototype.play = function ( startTime, weight ) { - - this.currentTime = startTime !== undefined ? startTime : 0; - this.weight = weight !== undefined ? weight: 1; - - this.isPlaying = true; - this.isPaused = false; - - this.reset(); - - THREE.AnimationHandler.addToUpdate( this ); - -}; - - -THREE.Animation.prototype.pause = function() { - - if ( this.isPaused === true ) { - - THREE.AnimationHandler.addToUpdate( this ); - - } else { - - THREE.AnimationHandler.removeFromUpdate( this ); - - } - - this.isPaused = !this.isPaused; - -}; - - -THREE.Animation.prototype.stop = function() { - - this.isPlaying = false; - this.isPaused = false; - THREE.AnimationHandler.removeFromUpdate( this ); - -}; - -THREE.Animation.prototype.reset = function () { - - for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) { - - var object = this.hierarchy[ h ]; - - object.matrixAutoUpdate = true; - - if ( object.animationCache === undefined ) { - - object.animationCache = {}; - - } - - if ( object.animationCache[this.data.name] === undefined ) { - - object.animationCache[this.data.name] = {}; - object.animationCache[this.data.name].prevKey = { pos: 0, rot: 0, scl: 0 }; - object.animationCache[this.data.name].nextKey = { pos: 0, rot: 0, scl: 0 }; - object.animationCache[this.data.name].originalMatrix = object instanceof THREE.Bone ? object.skinMatrix : object.matrix; - - } - - var animationCache = object.animationCache[this.data.name]; - - // Get keys to match our current time - - for ( var t = 0; t < 3; t ++ ) { - - var type = this.keyTypes[ t ]; - - var prevKey = this.data.hierarchy[ h ].keys[ 0 ]; - var nextKey = this.getNextKeyWith( type, h, 1 ); - - while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) { - - prevKey = nextKey; - nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 ); - - } - - animationCache.prevKey[ type ] = prevKey; - animationCache.nextKey[ type ] = nextKey; - - } - - } - -}; - - -THREE.Animation.prototype.update = (function(){ - - var points = []; - var target = new THREE.Vector3(); - var newVector = new THREE.Vector3(); - var newQuat = new THREE.Quaternion(); - - // Catmull-Rom spline - - var interpolateCatmullRom = function ( points, scale ) { - - var c = [], v3 = [], - point, intPoint, weight, w2, w3, - pa, pb, pc, pd; - - point = ( points.length - 1 ) * scale; - intPoint = Math.floor( point ); - weight = point - intPoint; - - c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1; - c[ 1 ] = intPoint; - c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1; - c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2; - - pa = points[ c[ 0 ] ]; - pb = points[ c[ 1 ] ]; - pc = points[ c[ 2 ] ]; - pd = points[ c[ 3 ] ]; - - w2 = weight * weight; - w3 = weight * w2; - - v3[ 0 ] = interpolate( pa[ 0 ], pb[ 0 ], pc[ 0 ], pd[ 0 ], weight, w2, w3 ); - v3[ 1 ] = interpolate( pa[ 1 ], pb[ 1 ], pc[ 1 ], pd[ 1 ], weight, w2, w3 ); - v3[ 2 ] = interpolate( pa[ 2 ], pb[ 2 ], pc[ 2 ], pd[ 2 ], weight, w2, w3 ); - - return v3; - - }; - - var interpolate = function ( p0, p1, p2, p3, t, t2, t3 ) { - - var v0 = ( p2 - p0 ) * 0.5, - v1 = ( p3 - p1 ) * 0.5; - - return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1; - - }; - - return function ( delta ) { - if ( this.isPlaying === false ) return; - - this.currentTime += delta * this.timeScale; - - if ( this.weight === 0 ) - return; - - // - - var vector; - var duration = this.data.length; - - if ( this.loop === true && this.currentTime > duration ) { - - this.currentTime %= duration; - this.reset(); - - } else if ( this.loop === false && this.currentTime > duration ) { - - this.stop(); - return; - - } - - for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) { - - var object = this.hierarchy[ h ]; - var animationCache = object.animationCache[this.data.name]; - - // loop through pos/rot/scl - - for ( var t = 0; t < 3; t ++ ) { - - // get keys - - var type = this.keyTypes[ t ]; - var prevKey = animationCache.prevKey[ type ]; - var nextKey = animationCache.nextKey[ type ]; - - if ( nextKey.time <= this.currentTime ) { - - prevKey = this.data.hierarchy[ h ].keys[ 0 ]; - nextKey = this.getNextKeyWith( type, h, 1 ); - - while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) { - - prevKey = nextKey; - nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 ); - - } - - animationCache.prevKey[ type ] = prevKey; - animationCache.nextKey[ type ] = nextKey; - - } - - object.matrixAutoUpdate = true; - object.matrixWorldNeedsUpdate = true; - - var scale = ( this.currentTime - prevKey.time ) / ( nextKey.time - prevKey.time ); - - var prevXYZ = prevKey[ type ]; - var nextXYZ = nextKey[ type ]; - - if ( scale < 0 ) scale = 0; - if ( scale > 1 ) scale = 1; - - // interpolate - - if ( type === "pos" ) { - - vector = object.position; - - if ( this.interpolationType === THREE.AnimationHandler.LINEAR ) { - - newVector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale; - newVector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale; - newVector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale; - - // blend - if (object instanceof THREE.Bone) { - - var proportionalWeight = this.weight / ( this.weight + object.accumulatedPosWeight ); - vector.lerp( newVector, proportionalWeight ); - object.accumulatedPosWeight += this.weight; - - } else - vector = newVector; - - } else if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM || - this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { - - points[ 0 ] = this.getPrevKeyWith( "pos", h, prevKey.index - 1 )[ "pos" ]; - points[ 1 ] = prevXYZ; - points[ 2 ] = nextXYZ; - points[ 3 ] = this.getNextKeyWith( "pos", h, nextKey.index + 1 )[ "pos" ]; - - scale = scale * 0.33 + 0.33; - - var currentPoint = interpolateCatmullRom( points, scale ); - - if ( object instanceof THREE.Bone ) { - - var proportionalWeight = this.weight / ( this.weight + object.accumulatedPosWeight ); - object.accumulatedPosWeight += this.weight; - - } - else - var proportionalWeight = 1; - - // blend - vector.x = vector.x + ( currentPoint[ 0 ] - vector.x ) * proportionalWeight; - vector.y = vector.y + ( currentPoint[ 1 ] - vector.y ) * proportionalWeight; - vector.z = vector.z + ( currentPoint[ 2 ] - vector.z ) * proportionalWeight; - - if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { - - var forwardPoint = interpolateCatmullRom( points, scale * 1.01 ); - - target.set( forwardPoint[ 0 ], forwardPoint[ 1 ], forwardPoint[ 2 ] ); - target.sub( vector ); - target.y = 0; - target.normalize(); - - var angle = Math.atan2( target.x, target.z ); - object.rotation.set( 0, angle, 0 ); - - } - - } - - } else if ( type === "rot" ) { - - THREE.Quaternion.slerp( prevXYZ, nextXYZ, newQuat, scale ); - - // Avoid paying the cost of an additional slerp if we don't have to - if ( !( object instanceof THREE.Bone ) ) { - - object.quaternion.copy(newQuat); - - } - else if ( object.accumulatedRotWeight === 0) { - - object.quaternion.copy(newQuat); - object.accumulatedRotWeight = this.weight; - - } - else { - - var proportionalWeight = this.weight / ( this.weight + object.accumulatedRotWeight ); - THREE.Quaternion.slerp( object.quaternion, newQuat, object.quaternion, proportionalWeight ); - object.accumulatedRotWeight += this.weight; - - } - - } else if ( type === "scl" ) { - - vector = object.scale; - - newVector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale; - newVector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale; - newVector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale; - - if ( object instanceof THREE.Bone ) { - - var proportionalWeight = this.weight / ( this.weight + object.accumulatedSclWeight); - vector.lerp( newVector, proportionalWeight ); - object.accumulatedSclWeight += this.weight; - - } else - vector = newVector; - - } - - } - - } - - return true; - - }; - -})(); - - - - - -// Get next key with - -THREE.Animation.prototype.getNextKeyWith = function ( type, h, key ) { - - var keys = this.data.hierarchy[ h ].keys; - - if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM || - this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { - - key = key < keys.length - 1 ? key : keys.length - 1; - - } else { - - key = key % keys.length; - - } - - for ( ; key < keys.length; key++ ) { - - if ( keys[ key ][ type ] !== undefined ) { - - return keys[ key ]; - - } - - } - - return this.data.hierarchy[ h ].keys[ 0 ]; - -}; - -// Get previous key with - -THREE.Animation.prototype.getPrevKeyWith = function ( type, h, key ) { - - var keys = this.data.hierarchy[ h ].keys; - - if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM || - this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) { - - key = key > 0 ? key : 0; - - } else { - - key = key >= 0 ? key : key + keys.length; - - } - - - for ( ; key >= 0; key -- ) { - - if ( keys[ key ][ type ] !== undefined ) { - - return keys[ key ]; - - } - - } - - return this.data.hierarchy[ h ].keys[ keys.length - 1 ]; - -}; - -/** - * @author mikael emtinger / http://gomo.se/ - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author khang duong - * @author erik kitson - */ - -THREE.KeyFrameAnimation = function ( root, data ) { - - this.root = root; - this.data = THREE.AnimationHandler.get( data ); - this.hierarchy = THREE.AnimationHandler.parse( root ); - this.currentTime = 0; - this.timeScale = 0.001; - this.isPlaying = false; - this.isPaused = true; - this.loop = true; - - // initialize to first keyframes - - for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) { - - var keys = this.data.hierarchy[h].keys, - sids = this.data.hierarchy[h].sids, - obj = this.hierarchy[h]; - - if ( keys.length && sids ) { - - for ( var s = 0; s < sids.length; s++ ) { - - var sid = sids[ s ], - next = this.getNextKeyWith( sid, h, 0 ); - - if ( next ) { - - next.apply( sid ); - - } - - } - - obj.matrixAutoUpdate = false; - this.data.hierarchy[h].node.updateMatrix(); - obj.matrixWorldNeedsUpdate = true; - - } - - } - -}; - -// Play - -THREE.KeyFrameAnimation.prototype.play = function ( startTime ) { - - this.currentTime = startTime !== undefined ? startTime : 0; - - if ( this.isPlaying === false ) { - - this.isPlaying = true; - - // reset key cache - - var h, hl = this.hierarchy.length, - object, - node; - - for ( h = 0; h < hl; h++ ) { - - object = this.hierarchy[ h ]; - node = this.data.hierarchy[ h ]; - - if ( node.animationCache === undefined ) { - - node.animationCache = {}; - node.animationCache.prevKey = null; - node.animationCache.nextKey = null; - node.animationCache.originalMatrix = object instanceof THREE.Bone ? object.skinMatrix : object.matrix; - - } - - var keys = this.data.hierarchy[h].keys; - - if (keys.length) { - - node.animationCache.prevKey = keys[ 0 ]; - node.animationCache.nextKey = keys[ 1 ]; - - this.startTime = Math.min( keys[0].time, this.startTime ); - this.endTime = Math.max( keys[keys.length - 1].time, this.endTime ); - - } - - } - - this.update( 0 ); - - } - - this.isPaused = false; - - THREE.AnimationHandler.addToUpdate( this ); - -}; - - - -// Pause - -THREE.KeyFrameAnimation.prototype.pause = function() { - - if( this.isPaused ) { - - THREE.AnimationHandler.addToUpdate( this ); - - } else { - - THREE.AnimationHandler.removeFromUpdate( this ); - - } - - this.isPaused = !this.isPaused; - -}; - - -// Stop - -THREE.KeyFrameAnimation.prototype.stop = function() { - - this.isPlaying = false; - this.isPaused = false; - - THREE.AnimationHandler.removeFromUpdate( this ); - - // reset JIT matrix and remove cache - - for ( var h = 0; h < this.data.hierarchy.length; h++ ) { - - var obj = this.hierarchy[ h ]; - var node = this.data.hierarchy[ h ]; - - if ( node.animationCache !== undefined ) { - - var original = node.animationCache.originalMatrix; - - if( obj instanceof THREE.Bone ) { - - original.copy( obj.skinMatrix ); - obj.skinMatrix = original; - - } else { - - original.copy( obj.matrix ); - obj.matrix = original; - - } - - delete node.animationCache; - - } - - } - -}; - - -// Update - -THREE.KeyFrameAnimation.prototype.update = function ( delta ) { - - if ( this.isPlaying === false ) return; - - this.currentTime += delta * this.timeScale; - - // - - var duration = this.data.length; - - if ( this.loop === true && this.currentTime > duration ) { - - this.currentTime %= duration; - - } - - this.currentTime = Math.min( this.currentTime, duration ); - - for ( var h = 0, hl = this.hierarchy.length; h < hl; h++ ) { - - var object = this.hierarchy[ h ]; - var node = this.data.hierarchy[ h ]; - - var keys = node.keys, - animationCache = node.animationCache; - - - if ( keys.length ) { - - var prevKey = animationCache.prevKey; - var nextKey = animationCache.nextKey; - - if ( nextKey.time <= this.currentTime ) { - - while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) { - - prevKey = nextKey; - nextKey = keys[ prevKey.index + 1 ]; - - } - - animationCache.prevKey = prevKey; - animationCache.nextKey = nextKey; - - } - - if ( nextKey.time >= this.currentTime ) { - - prevKey.interpolate( nextKey, this.currentTime ); - - } else { - - prevKey.interpolate( nextKey, nextKey.time ); - - } - - this.data.hierarchy[ h ].node.updateMatrix(); - object.matrixWorldNeedsUpdate = true; - - } - - } - -}; - -// Get next key with - -THREE.KeyFrameAnimation.prototype.getNextKeyWith = function( sid, h, key ) { - - var keys = this.data.hierarchy[ h ].keys; - key = key % keys.length; - - for ( ; key < keys.length; key++ ) { - - if ( keys[ key ].hasTarget( sid ) ) { - - return keys[ key ]; - - } - - } - - return keys[ 0 ]; - -}; - -// Get previous key with - -THREE.KeyFrameAnimation.prototype.getPrevKeyWith = function( sid, h, key ) { - - var keys = this.data.hierarchy[ h ].keys; - key = key >= 0 ? key : key + keys.length; - - for ( ; key >= 0; key-- ) { - - if ( keys[ key ].hasTarget( sid ) ) { - - return keys[ key ]; - - } - - } - - return keys[ keys.length - 1 ]; - -}; - -/** - * @author mrdoob / http://mrdoob.com - */ - -THREE.MorphAnimation = function ( mesh ) { - - this.mesh = mesh; - this.frames = mesh.morphTargetInfluences.length; - this.currentTime = 0; - this.duration = 1000; - this.loop = true; - - this.isPlaying = false; - -}; - -THREE.MorphAnimation.prototype = { - - play: function () { - - this.isPlaying = true; - - }, - - pause: function () { - - this.isPlaying = false; - }, - - update: ( function () { - - var lastFrame = 0; - var currentFrame = 0; - - return function ( delta ) { - - if ( this.isPlaying === false ) return; - - this.currentTime += delta; - - if ( this.loop === true && this.currentTime > this.duration ) { - - this.currentTime %= this.duration; - - } - - this.currentTime = Math.min( this.currentTime, this.duration ); - - var interpolation = this.duration / this.frames; - var frame = Math.floor( this.currentTime / interpolation ); - - if ( frame != currentFrame ) { - - this.mesh.morphTargetInfluences[ lastFrame ] = 0; - this.mesh.morphTargetInfluences[ currentFrame ] = 1; - this.mesh.morphTargetInfluences[ frame ] = 0; - - lastFrame = currentFrame; - currentFrame = frame; - - } - - this.mesh.morphTargetInfluences[ frame ] = ( this.currentTime % interpolation ) / interpolation; - this.mesh.morphTargetInfluences[ lastFrame ] = 1 - this.mesh.morphTargetInfluences[ frame ]; - - } - - } )() - -}; - -/** - * Camera for rendering cube maps - * - renders scene into axis-aligned cube - * - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.CubeCamera = function ( near, far, cubeResolution ) { - - THREE.Object3D.call( this ); - - var fov = 90, aspect = 1; - - var cameraPX = new THREE.PerspectiveCamera( fov, aspect, near, far ); - cameraPX.up.set( 0, -1, 0 ); - cameraPX.lookAt( new THREE.Vector3( 1, 0, 0 ) ); - this.add( cameraPX ); - - var cameraNX = new THREE.PerspectiveCamera( fov, aspect, near, far ); - cameraNX.up.set( 0, -1, 0 ); - cameraNX.lookAt( new THREE.Vector3( -1, 0, 0 ) ); - this.add( cameraNX ); - - var cameraPY = new THREE.PerspectiveCamera( fov, aspect, near, far ); - cameraPY.up.set( 0, 0, 1 ); - cameraPY.lookAt( new THREE.Vector3( 0, 1, 0 ) ); - this.add( cameraPY ); - - var cameraNY = new THREE.PerspectiveCamera( fov, aspect, near, far ); - cameraNY.up.set( 0, 0, -1 ); - cameraNY.lookAt( new THREE.Vector3( 0, -1, 0 ) ); - this.add( cameraNY ); - - var cameraPZ = new THREE.PerspectiveCamera( fov, aspect, near, far ); - cameraPZ.up.set( 0, -1, 0 ); - cameraPZ.lookAt( new THREE.Vector3( 0, 0, 1 ) ); - this.add( cameraPZ ); - - var cameraNZ = new THREE.PerspectiveCamera( fov, aspect, near, far ); - cameraNZ.up.set( 0, -1, 0 ); - cameraNZ.lookAt( new THREE.Vector3( 0, 0, -1 ) ); - this.add( cameraNZ ); - - this.renderTarget = new THREE.WebGLRenderTargetCube( cubeResolution, cubeResolution, { format: THREE.RGBFormat, magFilter: THREE.LinearFilter, minFilter: THREE.LinearFilter } ); - - this.updateCubeMap = function ( renderer, scene ) { - - var renderTarget = this.renderTarget; - var generateMipmaps = renderTarget.generateMipmaps; - - renderTarget.generateMipmaps = false; - - renderTarget.activeCubeFace = 0; - renderer.render( scene, cameraPX, renderTarget ); - - renderTarget.activeCubeFace = 1; - renderer.render( scene, cameraNX, renderTarget ); - - renderTarget.activeCubeFace = 2; - renderer.render( scene, cameraPY, renderTarget ); - - renderTarget.activeCubeFace = 3; - renderer.render( scene, cameraNY, renderTarget ); - - renderTarget.activeCubeFace = 4; - renderer.render( scene, cameraPZ, renderTarget ); - - renderTarget.generateMipmaps = generateMipmaps; - - renderTarget.activeCubeFace = 5; - renderer.render( scene, cameraNZ, renderTarget ); - - }; - -}; - -THREE.CubeCamera.prototype = Object.create( THREE.Object3D.prototype ); - -/** - * @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog - * - * A general perpose camera, for setting FOV, Lens Focal Length, - * and switching between perspective and orthographic views easily. - * Use this only if you do not wish to manage - * both a Orthographic and Perspective Camera - * - */ - - -THREE.CombinedCamera = function ( width, height, fov, near, far, orthoNear, orthoFar ) { - - THREE.Camera.call( this ); - - this.fov = fov; - - this.left = -width / 2; - this.right = width / 2 - this.top = height / 2; - this.bottom = -height / 2; - - // We could also handle the projectionMatrix internally, but just wanted to test nested camera objects - - this.cameraO = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, orthoNear, orthoFar ); - this.cameraP = new THREE.PerspectiveCamera( fov, width / height, near, far ); - - this.zoom = 1; - - this.toPerspective(); - - var aspect = width/height; - -}; - -THREE.CombinedCamera.prototype = Object.create( THREE.Camera.prototype ); - -THREE.CombinedCamera.prototype.toPerspective = function () { - - // Switches to the Perspective Camera - - this.near = this.cameraP.near; - this.far = this.cameraP.far; - - this.cameraP.fov = this.fov / this.zoom ; - - this.cameraP.updateProjectionMatrix(); - - this.projectionMatrix = this.cameraP.projectionMatrix; - - this.inPerspectiveMode = true; - this.inOrthographicMode = false; - -}; - -THREE.CombinedCamera.prototype.toOrthographic = function () { - - // Switches to the Orthographic camera estimating viewport from Perspective - - var fov = this.fov; - var aspect = this.cameraP.aspect; - var near = this.cameraP.near; - var far = this.cameraP.far; - - // The size that we set is the mid plane of the viewing frustum - - var hyperfocus = ( near + far ) / 2; - - var halfHeight = Math.tan( fov / 2 ) * hyperfocus; - var planeHeight = 2 * halfHeight; - var planeWidth = planeHeight * aspect; - var halfWidth = planeWidth / 2; - - halfHeight /= this.zoom; - halfWidth /= this.zoom; - - this.cameraO.left = -halfWidth; - this.cameraO.right = halfWidth; - this.cameraO.top = halfHeight; - this.cameraO.bottom = -halfHeight; - - // this.cameraO.left = -farHalfWidth; - // this.cameraO.right = farHalfWidth; - // this.cameraO.top = farHalfHeight; - // this.cameraO.bottom = -farHalfHeight; - - // this.cameraO.left = this.left / this.zoom; - // this.cameraO.right = this.right / this.zoom; - // this.cameraO.top = this.top / this.zoom; - // this.cameraO.bottom = this.bottom / this.zoom; - - this.cameraO.updateProjectionMatrix(); - - this.near = this.cameraO.near; - this.far = this.cameraO.far; - this.projectionMatrix = this.cameraO.projectionMatrix; - - this.inPerspectiveMode = false; - this.inOrthographicMode = true; - -}; - - -THREE.CombinedCamera.prototype.setSize = function( width, height ) { - - this.cameraP.aspect = width / height; - this.left = -width / 2; - this.right = width / 2 - this.top = height / 2; - this.bottom = -height / 2; - -}; - - -THREE.CombinedCamera.prototype.setFov = function( fov ) { - - this.fov = fov; - - if ( this.inPerspectiveMode ) { - - this.toPerspective(); - - } else { - - this.toOrthographic(); - - } - -}; - -// For mantaining similar API with PerspectiveCamera - -THREE.CombinedCamera.prototype.updateProjectionMatrix = function() { - - if ( this.inPerspectiveMode ) { - - this.toPerspective(); - - } else { - - this.toPerspective(); - this.toOrthographic(); - - } - -}; - -/* -* Uses Focal Length (in mm) to estimate and set FOV -* 35mm (fullframe) camera is used if frame size is not specified; -* Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html -*/ -THREE.CombinedCamera.prototype.setLens = function ( focalLength, frameHeight ) { - - if ( frameHeight === undefined ) frameHeight = 24; - - var fov = 2 * THREE.Math.radToDeg( Math.atan( frameHeight / ( focalLength * 2 ) ) ); - - this.setFov( fov ); - - return fov; -}; - - -THREE.CombinedCamera.prototype.setZoom = function( zoom ) { - - this.zoom = zoom; - - if ( this.inPerspectiveMode ) { - - this.toPerspective(); - - } else { - - this.toOrthographic(); - - } - -}; - -THREE.CombinedCamera.prototype.toFrontView = function() { - - this.rotation.x = 0; - this.rotation.y = 0; - this.rotation.z = 0; - - // should we be modifing the matrix instead? - - this.rotationAutoUpdate = false; - -}; - -THREE.CombinedCamera.prototype.toBackView = function() { - - this.rotation.x = 0; - this.rotation.y = Math.PI; - this.rotation.z = 0; - this.rotationAutoUpdate = false; - -}; - -THREE.CombinedCamera.prototype.toLeftView = function() { - - this.rotation.x = 0; - this.rotation.y = - Math.PI / 2; - this.rotation.z = 0; - this.rotationAutoUpdate = false; - -}; - -THREE.CombinedCamera.prototype.toRightView = function() { - - this.rotation.x = 0; - this.rotation.y = Math.PI / 2; - this.rotation.z = 0; - this.rotationAutoUpdate = false; - -}; - -THREE.CombinedCamera.prototype.toTopView = function() { - - this.rotation.x = - Math.PI / 2; - this.rotation.y = 0; - this.rotation.z = 0; - this.rotationAutoUpdate = false; - -}; - -THREE.CombinedCamera.prototype.toBottomView = function() { - - this.rotation.x = Math.PI / 2; - this.rotation.y = 0; - this.rotation.z = 0; - this.rotationAutoUpdate = false; - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as - */ - -THREE.BoxGeometry = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) { - - THREE.Geometry.call( this ); - - this.parameters = { - width: width, - height: height, - depth: depth, - widthSegments: widthSegments, - heightSegments: heightSegments, - depthSegments: depthSegments - }; - - this.widthSegments = widthSegments || 1; - this.heightSegments = heightSegments || 1; - this.depthSegments = depthSegments || 1; - - var scope = this; - - var width_half = width / 2; - var height_half = height / 2; - var depth_half = depth / 2; - - buildPlane( 'z', 'y', - 1, - 1, depth, height, width_half, 0 ); // px - buildPlane( 'z', 'y', 1, - 1, depth, height, - width_half, 1 ); // nx - buildPlane( 'x', 'z', 1, 1, width, depth, height_half, 2 ); // py - buildPlane( 'x', 'z', 1, - 1, width, depth, - height_half, 3 ); // ny - buildPlane( 'x', 'y', 1, - 1, width, height, depth_half, 4 ); // pz - buildPlane( 'x', 'y', - 1, - 1, width, height, - depth_half, 5 ); // nz - - function buildPlane( u, v, udir, vdir, width, height, depth, materialIndex ) { - - var w, ix, iy, - gridX = scope.widthSegments, - gridY = scope.heightSegments, - width_half = width / 2, - height_half = height / 2, - offset = scope.vertices.length; - - if ( ( u === 'x' && v === 'y' ) || ( u === 'y' && v === 'x' ) ) { - - w = 'z'; - - } else if ( ( u === 'x' && v === 'z' ) || ( u === 'z' && v === 'x' ) ) { - - w = 'y'; - gridY = scope.depthSegments; - - } else if ( ( u === 'z' && v === 'y' ) || ( u === 'y' && v === 'z' ) ) { - - w = 'x'; - gridX = scope.depthSegments; - - } - - var gridX1 = gridX + 1, - gridY1 = gridY + 1, - segment_width = width / gridX, - segment_height = height / gridY, - normal = new THREE.Vector3(); - - normal[ w ] = depth > 0 ? 1 : - 1; - - for ( iy = 0; iy < gridY1; iy ++ ) { - - for ( ix = 0; ix < gridX1; ix ++ ) { - - var vector = new THREE.Vector3(); - vector[ u ] = ( ix * segment_width - width_half ) * udir; - vector[ v ] = ( iy * segment_height - height_half ) * vdir; - vector[ w ] = depth; - - scope.vertices.push( vector ); - - } - - } - - for ( iy = 0; iy < gridY; iy++ ) { - - for ( ix = 0; ix < gridX; ix++ ) { - - var a = ix + gridX1 * iy; - var b = ix + gridX1 * ( iy + 1 ); - var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); - var d = ( ix + 1 ) + gridX1 * iy; - - var uva = new THREE.Vector2( ix / gridX, 1 - iy / gridY ); - var uvb = new THREE.Vector2( ix / gridX, 1 - ( iy + 1 ) / gridY ); - var uvc = new THREE.Vector2( ( ix + 1 ) / gridX, 1 - ( iy + 1 ) / gridY ); - var uvd = new THREE.Vector2( ( ix + 1 ) / gridX, 1 - iy / gridY ); - - var face = new THREE.Face3( a + offset, b + offset, d + offset ); - face.normal.copy( normal ); - face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() ); - face.materialIndex = materialIndex; - - scope.faces.push( face ); - scope.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] ); - - face = new THREE.Face3( b + offset, c + offset, d + offset ); - face.normal.copy( normal ); - face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() ); - face.materialIndex = materialIndex; - - scope.faces.push( face ); - scope.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] ); - - } - - } - - } - - this.mergeVertices(); - -}; - -THREE.BoxGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author hughes - */ - -THREE.CircleGeometry = function ( radius, segments, thetaStart, thetaLength ) { - - THREE.Geometry.call( this ); - - this.parameters = { - radius: radius, - segments: segments, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - - radius = radius || 50; - segments = segments !== undefined ? Math.max( 3, segments ) : 8; - - thetaStart = thetaStart !== undefined ? thetaStart : 0; - thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; - - var i, uvs = [], - center = new THREE.Vector3(), centerUV = new THREE.Vector2( 0.5, 0.5 ); - - this.vertices.push(center); - uvs.push( centerUV ); - - for ( i = 0; i <= segments; i ++ ) { - - var vertex = new THREE.Vector3(); - var segment = thetaStart + i / segments * thetaLength; - - vertex.x = radius * Math.cos( segment ); - vertex.y = radius * Math.sin( segment ); - - this.vertices.push( vertex ); - uvs.push( new THREE.Vector2( ( vertex.x / radius + 1 ) / 2, ( vertex.y / radius + 1 ) / 2 ) ); - - } - - var n = new THREE.Vector3( 0, 0, 1 ); - - for ( i = 1; i <= segments; i ++ ) { - - this.faces.push( new THREE.Face3( i, i + 1, 0, [ n.clone(), n.clone(), n.clone() ] ) ); - this.faceVertexUvs[ 0 ].push( [ uvs[ i ].clone(), uvs[ i + 1 ].clone(), centerUV.clone() ] ); - - } - - this.computeFaceNormals(); - - this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius ); - -}; - -THREE.CircleGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -// DEPRECATED - -THREE.CubeGeometry = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) { - console.warn( 'DEPRECATED: THREE.CubeGeometry is deprecated. Use THREE.BoxGeometry instead.' ); - return new THREE.BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ); - }; -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.CylinderGeometry = function ( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded ) { - - THREE.Geometry.call( this ); - - this.parameters = { - radiusTop: radiusTop, - radiusBottom: radiusBottom, - height: height, - radialSegments: radialSegments, - heightSegments: heightSegments, - openEnded: openEnded - }; - - radiusTop = radiusTop !== undefined ? radiusTop : 20; - radiusBottom = radiusBottom !== undefined ? radiusBottom : 20; - height = height !== undefined ? height : 100; - - radialSegments = radialSegments || 8; - heightSegments = heightSegments || 1; - - openEnded = openEnded !== undefined ? openEnded : false; - - var heightHalf = height / 2; - - var x, y, vertices = [], uvs = []; - - for ( y = 0; y <= heightSegments; y ++ ) { - - var verticesRow = []; - var uvsRow = []; - - var v = y / heightSegments; - var radius = v * ( radiusBottom - radiusTop ) + radiusTop; - - for ( x = 0; x <= radialSegments; x ++ ) { - - var u = x / radialSegments; - - var vertex = new THREE.Vector3(); - vertex.x = radius * Math.sin( u * Math.PI * 2 ); - vertex.y = - v * height + heightHalf; - vertex.z = radius * Math.cos( u * Math.PI * 2 ); - - this.vertices.push( vertex ); - - verticesRow.push( this.vertices.length - 1 ); - uvsRow.push( new THREE.Vector2( u, 1 - v ) ); - - } - - vertices.push( verticesRow ); - uvs.push( uvsRow ); - - } - - var tanTheta = ( radiusBottom - radiusTop ) / height; - var na, nb; - - for ( x = 0; x < radialSegments; x ++ ) { - - if ( radiusTop !== 0 ) { - - na = this.vertices[ vertices[ 0 ][ x ] ].clone(); - nb = this.vertices[ vertices[ 0 ][ x + 1 ] ].clone(); - - } else { - - na = this.vertices[ vertices[ 1 ][ x ] ].clone(); - nb = this.vertices[ vertices[ 1 ][ x + 1 ] ].clone(); - - } - - na.setY( Math.sqrt( na.x * na.x + na.z * na.z ) * tanTheta ).normalize(); - nb.setY( Math.sqrt( nb.x * nb.x + nb.z * nb.z ) * tanTheta ).normalize(); - - for ( y = 0; y < heightSegments; y ++ ) { - - var v1 = vertices[ y ][ x ]; - var v2 = vertices[ y + 1 ][ x ]; - var v3 = vertices[ y + 1 ][ x + 1 ]; - var v4 = vertices[ y ][ x + 1 ]; - - var n1 = na.clone(); - var n2 = na.clone(); - var n3 = nb.clone(); - var n4 = nb.clone(); - - var uv1 = uvs[ y ][ x ].clone(); - var uv2 = uvs[ y + 1 ][ x ].clone(); - var uv3 = uvs[ y + 1 ][ x + 1 ].clone(); - var uv4 = uvs[ y ][ x + 1 ].clone(); - - this.faces.push( new THREE.Face3( v1, v2, v4, [ n1, n2, n4 ] ) ); - this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv4 ] ); - - this.faces.push( new THREE.Face3( v2, v3, v4, [ n2.clone(), n3, n4.clone() ] ) ); - this.faceVertexUvs[ 0 ].push( [ uv2.clone(), uv3, uv4.clone() ] ); - - } - - } - - // top cap - - if ( openEnded === false && radiusTop > 0 ) { - - this.vertices.push( new THREE.Vector3( 0, heightHalf, 0 ) ); - - for ( x = 0; x < radialSegments; x ++ ) { - - var v1 = vertices[ 0 ][ x ]; - var v2 = vertices[ 0 ][ x + 1 ]; - var v3 = this.vertices.length - 1; - - var n1 = new THREE.Vector3( 0, 1, 0 ); - var n2 = new THREE.Vector3( 0, 1, 0 ); - var n3 = new THREE.Vector3( 0, 1, 0 ); - - var uv1 = uvs[ 0 ][ x ].clone(); - var uv2 = uvs[ 0 ][ x + 1 ].clone(); - var uv3 = new THREE.Vector2( uv2.x, 0 ); - - this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) ); - this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] ); - - } - - } - - // bottom cap - - if ( openEnded === false && radiusBottom > 0 ) { - - this.vertices.push( new THREE.Vector3( 0, - heightHalf, 0 ) ); - - for ( x = 0; x < radialSegments; x ++ ) { - - var v1 = vertices[ y ][ x + 1 ]; - var v2 = vertices[ y ][ x ]; - var v3 = this.vertices.length - 1; - - var n1 = new THREE.Vector3( 0, - 1, 0 ); - var n2 = new THREE.Vector3( 0, - 1, 0 ); - var n3 = new THREE.Vector3( 0, - 1, 0 ); - - var uv1 = uvs[ y ][ x + 1 ].clone(); - var uv2 = uvs[ y ][ x ].clone(); - var uv3 = new THREE.Vector2( uv2.x, 1 ); - - this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) ); - this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] ); - - } - - } - - this.computeFaceNormals(); - -} - -THREE.CylinderGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author zz85 / http://www.lab4games.net/zz85/blog - * - * Creates extruded geometry from a path shape. - * - * parameters = { - * - * curveSegments: , // number of points on the curves - * steps: , // number of points for z-side extrusions / used for subdividing segements of extrude spline too - * amount: , // Depth to extrude the shape - * - * bevelEnabled: , // turn on bevel - * bevelThickness: , // how deep into the original shape bevel goes - * bevelSize: , // how far from shape outline is bevel - * bevelSegments: , // number of bevel layers - * - * extrudePath: // 3d spline path to extrude shape along. (creates Frames if .frames aren't defined) - * frames: // containing arrays of tangents, normals, binormals - * - * material: // material index for front and back faces - * extrudeMaterial: // material index for extrusion and beveled faces - * uvGenerator: // object that provides UV generator functions - * - * } - **/ - -THREE.ExtrudeGeometry = function ( shapes, options ) { - - if ( typeof( shapes ) === "undefined" ) { - shapes = []; - return; - } - - THREE.Geometry.call( this ); - - shapes = shapes instanceof Array ? shapes : [ shapes ]; - - this.shapebb = shapes[ shapes.length - 1 ].getBoundingBox(); - - this.addShapeList( shapes, options ); - - this.computeFaceNormals(); - - // can't really use automatic vertex normals - // as then front and back sides get smoothed too - // should do separate smoothing just for sides - - //this.computeVertexNormals(); - - //console.log( "took", ( Date.now() - startTime ) ); - -}; - -THREE.ExtrudeGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -THREE.ExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) { - var sl = shapes.length; - - for ( var s = 0; s < sl; s ++ ) { - var shape = shapes[ s ]; - this.addShape( shape, options ); - } -}; - -THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) { - - var amount = options.amount !== undefined ? options.amount : 100; - - var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10 - var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8 - var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3; - - var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false - - var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; - - var steps = options.steps !== undefined ? options.steps : 1; - - var extrudePath = options.extrudePath; - var extrudePts, extrudeByPath = false; - - var material = options.material; - var extrudeMaterial = options.extrudeMaterial; - - // Use default WorldUVGenerator if no UV generators are specified. - var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : THREE.ExtrudeGeometry.WorldUVGenerator; - - var shapebb = this.shapebb; - //shapebb = shape.getBoundingBox(); - - - - var splineTube, binormal, normal, position2; - if ( extrudePath ) { - - extrudePts = extrudePath.getSpacedPoints( steps ); - - extrudeByPath = true; - bevelEnabled = false; // bevels not supported for path extrusion - - // SETUP TNB variables - - // Reuse TNB from TubeGeomtry for now. - // TODO1 - have a .isClosed in spline? - - splineTube = options.frames !== undefined ? options.frames : new THREE.TubeGeometry.FrenetFrames(extrudePath, steps, false); - - // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); - - binormal = new THREE.Vector3(); - normal = new THREE.Vector3(); - position2 = new THREE.Vector3(); - - } - - // Safeguards if bevels are not enabled - - if ( ! bevelEnabled ) { - - bevelSegments = 0; - bevelThickness = 0; - bevelSize = 0; - - } - - // Variables initalization - - var ahole, h, hl; // looping of holes - var scope = this; - var bevelPoints = []; - - var shapesOffset = this.vertices.length; - - var shapePoints = shape.extractPoints( curveSegments ); - - var vertices = shapePoints.shape; - var holes = shapePoints.holes; - - var reverse = !THREE.Shape.Utils.isClockWise( vertices ) ; - - if ( reverse ) { - - vertices = vertices.reverse(); - - // Maybe we should also check if holes are in the opposite direction, just to be safe ... - - for ( h = 0, hl = holes.length; h < hl; h ++ ) { - - ahole = holes[ h ]; - - if ( THREE.Shape.Utils.isClockWise( ahole ) ) { - - holes[ h ] = ahole.reverse(); - - } - - } - - reverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)! - - } - - - var faces = THREE.Shape.Utils.triangulateShape ( vertices, holes ); - - /* Vertices */ - - var contour = vertices; // vertices has all points but contour has only points of circumference - - for ( h = 0, hl = holes.length; h < hl; h ++ ) { - - ahole = holes[ h ]; - - vertices = vertices.concat( ahole ); - - } - - - function scalePt2 ( pt, vec, size ) { - - if ( !vec ) console.log( "die" ); - - return vec.clone().multiplyScalar( size ).add( pt ); - - } - - var b, bs, t, z, - vert, vlen = vertices.length, - face, flen = faces.length, - cont, clen = contour.length; - - - // Find directions for point movement - - var RAD_TO_DEGREES = 180 / Math.PI; - - - function getBevelVec( inPt, inPrev, inNext ) { - - var EPSILON = 0.0000000001; - var sign = THREE.Math.sign; - - // computes for inPt the corresponding point inPt' on a new contour - // shiftet by 1 unit (length of normalized vector) to the left - // if we walk along contour clockwise, this new contour is outside the old one - // - // inPt' is the intersection of the two lines parallel to the two - // adjacent edges of inPt at a distance of 1 unit on the left side. - - var v_trans_x, v_trans_y, shrink_by = 1; // resulting translation vector for inPt - - // good reading for geometry algorithms (here: line-line intersection) - // http://geomalgorithms.com/a05-_intersect-1.html - - var v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y; - var v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y; - - var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y ); - - // check for colinear edges - var colinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x ); - - if ( Math.abs( colinear0 ) > EPSILON ) { // not colinear - - // length of vectors for normalizing - - var v_prev_len = Math.sqrt( v_prev_lensq ); - var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y ); - - // shift adjacent points by unit vectors to the left - - var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len ); - var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len ); - - var ptNextShift_x = ( inNext.x - v_next_y / v_next_len ); - var ptNextShift_y = ( inNext.y + v_next_x / v_next_len ); - - // scaling factor for v_prev to intersection point - - var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y - - ( ptNextShift_y - ptPrevShift_y ) * v_next_x ) / - ( v_prev_x * v_next_y - v_prev_y * v_next_x ); - - // vector from inPt to intersection point - - v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x ); - v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y ); - - // Don't normalize!, otherwise sharp corners become ugly - // but prevent crazy spikes - var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y ) - if ( v_trans_lensq <= 2 ) { - return new THREE.Vector2( v_trans_x, v_trans_y ); - } else { - shrink_by = Math.sqrt( v_trans_lensq / 2 ); - } - - } else { // handle special case of colinear edges - - var direction_eq = false; // assumes: opposite - if ( v_prev_x > EPSILON ) { - if ( v_next_x > EPSILON ) { direction_eq = true; } - } else { - if ( v_prev_x < -EPSILON ) { - if ( v_next_x < -EPSILON ) { direction_eq = true; } - } else { - if ( sign(v_prev_y) == sign(v_next_y) ) { direction_eq = true; } - } - } - - if ( direction_eq ) { - // console.log("Warning: lines are a straight sequence"); - v_trans_x = -v_prev_y; - v_trans_y = v_prev_x; - shrink_by = Math.sqrt( v_prev_lensq ); - } else { - // console.log("Warning: lines are a straight spike"); - v_trans_x = v_prev_x; - v_trans_y = v_prev_y; - shrink_by = Math.sqrt( v_prev_lensq / 2 ); - } - - } - - return new THREE.Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by ); - - } - - - var contourMovements = []; - - for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { - - if ( j === il ) j = 0; - if ( k === il ) k = 0; - - // (j)---(i)---(k) - // console.log('i,j,k', i, j , k) - - var pt_i = contour[ i ]; - var pt_j = contour[ j ]; - var pt_k = contour[ k ]; - - contourMovements[ i ]= getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); - - } - - var holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat(); - - for ( h = 0, hl = holes.length; h < hl; h ++ ) { - - ahole = holes[ h ]; - - oneHoleMovements = []; - - for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { - - if ( j === il ) j = 0; - if ( k === il ) k = 0; - - // (j)---(i)---(k) - oneHoleMovements[ i ]= getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); - - } - - holesMovements.push( oneHoleMovements ); - verticesMovements = verticesMovements.concat( oneHoleMovements ); - - } - - - // Loop bevelSegments, 1 for the front, 1 for the back - - for ( b = 0; b < bevelSegments; b ++ ) { - //for ( b = bevelSegments; b > 0; b -- ) { - - t = b / bevelSegments; - z = bevelThickness * ( 1 - t ); - - //z = bevelThickness * t; - bs = bevelSize * ( Math.sin ( t * Math.PI/2 ) ) ; // curved - //bs = bevelSize * t ; // linear - - // contract shape - - for ( i = 0, il = contour.length; i < il; i ++ ) { - - vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); - - v( vert.x, vert.y, - z ); - - } - - // expand holes - - for ( h = 0, hl = holes.length; h < hl; h++ ) { - - ahole = holes[ h ]; - oneHoleMovements = holesMovements[ h ]; - - for ( i = 0, il = ahole.length; i < il; i++ ) { - - vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); - - v( vert.x, vert.y, -z ); - - } - - } - - } - - bs = bevelSize; - - // Back facing vertices - - for ( i = 0; i < vlen; i ++ ) { - - vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; - - if ( !extrudeByPath ) { - - v( vert.x, vert.y, 0 ); - - } else { - - // v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x ); - - normal.copy( splineTube.normals[0] ).multiplyScalar(vert.x); - binormal.copy( splineTube.binormals[0] ).multiplyScalar(vert.y); - - position2.copy( extrudePts[0] ).add(normal).add(binormal); - - v( position2.x, position2.y, position2.z ); - - } - - } - - // Add stepped vertices... - // Including front facing vertices - - var s; - - for ( s = 1; s <= steps; s ++ ) { - - for ( i = 0; i < vlen; i ++ ) { - - vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; - - if ( !extrudeByPath ) { - - v( vert.x, vert.y, amount / steps * s ); - - } else { - - // v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x ); - - normal.copy( splineTube.normals[s] ).multiplyScalar( vert.x ); - binormal.copy( splineTube.binormals[s] ).multiplyScalar( vert.y ); - - position2.copy( extrudePts[s] ).add( normal ).add( binormal ); - - v( position2.x, position2.y, position2.z ); - - } - - } - - } - - - // Add bevel segments planes - - //for ( b = 1; b <= bevelSegments; b ++ ) { - for ( b = bevelSegments - 1; b >= 0; b -- ) { - - t = b / bevelSegments; - z = bevelThickness * ( 1 - t ); - //bs = bevelSize * ( 1-Math.sin ( ( 1 - t ) * Math.PI/2 ) ); - bs = bevelSize * Math.sin ( t * Math.PI/2 ) ; - - // contract shape - - for ( i = 0, il = contour.length; i < il; i ++ ) { - - vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); - v( vert.x, vert.y, amount + z ); - - } - - // expand holes - - for ( h = 0, hl = holes.length; h < hl; h ++ ) { - - ahole = holes[ h ]; - oneHoleMovements = holesMovements[ h ]; - - for ( i = 0, il = ahole.length; i < il; i ++ ) { - - vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); - - if ( !extrudeByPath ) { - - v( vert.x, vert.y, amount + z ); - - } else { - - v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z ); - - } - - } - - } - - } - - /* Faces */ - - // Top and bottom faces - - buildLidFaces(); - - // Sides faces - - buildSideFaces(); - - - ///// Internal functions - - function buildLidFaces() { - - if ( bevelEnabled ) { - - var layer = 0 ; // steps + 1 - var offset = vlen * layer; - - // Bottom faces - - for ( i = 0; i < flen; i ++ ) { - - face = faces[ i ]; - f3( face[ 2 ]+ offset, face[ 1 ]+ offset, face[ 0 ] + offset, true ); - - } - - layer = steps + bevelSegments * 2; - offset = vlen * layer; - - // Top faces - - for ( i = 0; i < flen; i ++ ) { - - face = faces[ i ]; - f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset, false ); - - } - - } else { - - // Bottom faces - - for ( i = 0; i < flen; i++ ) { - - face = faces[ i ]; - f3( face[ 2 ], face[ 1 ], face[ 0 ], true ); - - } - - // Top faces - - for ( i = 0; i < flen; i ++ ) { - - face = faces[ i ]; - f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps, false ); - - } - } - - } - - // Create faces for the z-sides of the shape - - function buildSideFaces() { - - var layeroffset = 0; - sidewalls( contour, layeroffset ); - layeroffset += contour.length; - - for ( h = 0, hl = holes.length; h < hl; h ++ ) { - - ahole = holes[ h ]; - sidewalls( ahole, layeroffset ); - - //, true - layeroffset += ahole.length; - - } - - } - - function sidewalls( contour, layeroffset ) { - - var j, k; - i = contour.length; - - while ( --i >= 0 ) { - - j = i; - k = i - 1; - if ( k < 0 ) k = contour.length - 1; - - //console.log('b', i,j, i-1, k,vertices.length); - - var s = 0, sl = steps + bevelSegments * 2; - - for ( s = 0; s < sl; s ++ ) { - - var slen1 = vlen * s; - var slen2 = vlen * ( s + 1 ); - - var a = layeroffset + j + slen1, - b = layeroffset + k + slen1, - c = layeroffset + k + slen2, - d = layeroffset + j + slen2; - - f4( a, b, c, d, contour, s, sl, j, k ); - - } - } - - } - - - function v( x, y, z ) { - - scope.vertices.push( new THREE.Vector3( x, y, z ) ); - - } - - function f3( a, b, c, isBottom ) { - - a += shapesOffset; - b += shapesOffset; - c += shapesOffset; - - // normal, color, material - scope.faces.push( new THREE.Face3( a, b, c, null, null, material ) ); - - var uvs = isBottom ? uvgen.generateBottomUV( scope, shape, options, a, b, c ) : uvgen.generateTopUV( scope, shape, options, a, b, c ); - - scope.faceVertexUvs[ 0 ].push( uvs ); - - } - - function f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) { - - a += shapesOffset; - b += shapesOffset; - c += shapesOffset; - d += shapesOffset; - - scope.faces.push( new THREE.Face3( a, b, d, null, null, extrudeMaterial ) ); - scope.faces.push( new THREE.Face3( b, c, d, null, null, extrudeMaterial ) ); - - var uvs = uvgen.generateSideWallUV( scope, shape, wallContour, options, a, b, c, d, - stepIndex, stepsLength, contourIndex1, contourIndex2 ); - - scope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] ); - scope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] ); - - } - -}; - -THREE.ExtrudeGeometry.WorldUVGenerator = { - - generateTopUV: function( geometry, extrudedShape, extrudeOptions, indexA, indexB, indexC ) { - var ax = geometry.vertices[ indexA ].x, - ay = geometry.vertices[ indexA ].y, - - bx = geometry.vertices[ indexB ].x, - by = geometry.vertices[ indexB ].y, - - cx = geometry.vertices[ indexC ].x, - cy = geometry.vertices[ indexC ].y; - - return [ - new THREE.Vector2( ax, ay ), - new THREE.Vector2( bx, by ), - new THREE.Vector2( cx, cy ) - ]; - - }, - - generateBottomUV: function( geometry, extrudedShape, extrudeOptions, indexA, indexB, indexC ) { - - return this.generateTopUV( geometry, extrudedShape, extrudeOptions, indexA, indexB, indexC ); - - }, - - generateSideWallUV: function( geometry, extrudedShape, wallContour, extrudeOptions, - indexA, indexB, indexC, indexD, stepIndex, stepsLength, - contourIndex1, contourIndex2 ) { - - var ax = geometry.vertices[ indexA ].x, - ay = geometry.vertices[ indexA ].y, - az = geometry.vertices[ indexA ].z, - - bx = geometry.vertices[ indexB ].x, - by = geometry.vertices[ indexB ].y, - bz = geometry.vertices[ indexB ].z, - - cx = geometry.vertices[ indexC ].x, - cy = geometry.vertices[ indexC ].y, - cz = geometry.vertices[ indexC ].z, - - dx = geometry.vertices[ indexD ].x, - dy = geometry.vertices[ indexD ].y, - dz = geometry.vertices[ indexD ].z; - - if ( Math.abs( ay - by ) < 0.01 ) { - return [ - new THREE.Vector2( ax, 1 - az ), - new THREE.Vector2( bx, 1 - bz ), - new THREE.Vector2( cx, 1 - cz ), - new THREE.Vector2( dx, 1 - dz ) - ]; - } else { - return [ - new THREE.Vector2( ay, 1 - az ), - new THREE.Vector2( by, 1 - bz ), - new THREE.Vector2( cy, 1 - cz ), - new THREE.Vector2( dy, 1 - dz ) - ]; - } - } -}; - -THREE.ExtrudeGeometry.__v1 = new THREE.Vector2(); -THREE.ExtrudeGeometry.__v2 = new THREE.Vector2(); -THREE.ExtrudeGeometry.__v3 = new THREE.Vector2(); -THREE.ExtrudeGeometry.__v4 = new THREE.Vector2(); -THREE.ExtrudeGeometry.__v5 = new THREE.Vector2(); -THREE.ExtrudeGeometry.__v6 = new THREE.Vector2(); - -/** - * @author jonobr1 / http://jonobr1.com - * - * Creates a one-sided polygonal geometry from a path shape. Similar to - * ExtrudeGeometry. - * - * parameters = { - * - * curveSegments: , // number of points on the curves. NOT USED AT THE MOMENT. - * - * material: // material index for front and back faces - * uvGenerator: // object that provides UV generator functions - * - * } - **/ - -THREE.ShapeGeometry = function ( shapes, options ) { - - THREE.Geometry.call( this ); - - if ( shapes instanceof Array === false ) shapes = [ shapes ]; - - this.shapebb = shapes[ shapes.length - 1 ].getBoundingBox(); - - this.addShapeList( shapes, options ); - - this.computeFaceNormals(); - -}; - -THREE.ShapeGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * Add an array of shapes to THREE.ShapeGeometry. - */ -THREE.ShapeGeometry.prototype.addShapeList = function ( shapes, options ) { - - for ( var i = 0, l = shapes.length; i < l; i++ ) { - - this.addShape( shapes[ i ], options ); - - } - - return this; - -}; - -/** - * Adds a shape to THREE.ShapeGeometry, based on THREE.ExtrudeGeometry. - */ -THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) { - - if ( options === undefined ) options = {}; - var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; - - var material = options.material; - var uvgen = options.UVGenerator === undefined ? THREE.ExtrudeGeometry.WorldUVGenerator : options.UVGenerator; - - var shapebb = this.shapebb; - - // - - var i, l, hole, s; - - var shapesOffset = this.vertices.length; - var shapePoints = shape.extractPoints( curveSegments ); - - var vertices = shapePoints.shape; - var holes = shapePoints.holes; - - var reverse = !THREE.Shape.Utils.isClockWise( vertices ); - - if ( reverse ) { - - vertices = vertices.reverse(); - - // Maybe we should also check if holes are in the opposite direction, just to be safe... - - for ( i = 0, l = holes.length; i < l; i++ ) { - - hole = holes[ i ]; - - if ( THREE.Shape.Utils.isClockWise( hole ) ) { - - holes[ i ] = hole.reverse(); - - } - - } - - reverse = false; - - } - - var faces = THREE.Shape.Utils.triangulateShape( vertices, holes ); - - // Vertices - - var contour = vertices; - - for ( i = 0, l = holes.length; i < l; i++ ) { - - hole = holes[ i ]; - vertices = vertices.concat( hole ); - - } - - // - - var vert, vlen = vertices.length; - var face, flen = faces.length; - var cont, clen = contour.length; - - for ( i = 0; i < vlen; i++ ) { - - vert = vertices[ i ]; - - this.vertices.push( new THREE.Vector3( vert.x, vert.y, 0 ) ); - - } - - for ( i = 0; i < flen; i++ ) { - - face = faces[ i ]; - - var a = face[ 0 ] + shapesOffset; - var b = face[ 1 ] + shapesOffset; - var c = face[ 2 ] + shapesOffset; - - this.faces.push( new THREE.Face3( a, b, c, null, null, material ) ); - this.faceVertexUvs[ 0 ].push( uvgen.generateBottomUV( this, shape, options, a, b, c ) ); - - } - -}; - -/** - * @author astrodud / http://astrodud.isgreat.org/ - * @author zz85 / https://github.com/zz85 - * @author bhouston / http://exocortex.com - */ - -// points - to create a closed torus, one must use a set of points -// like so: [ a, b, c, d, a ], see first is the same as last. -// segments - the number of circumference segments to create -// phiStart - the starting radian -// phiLength - the radian (0 to 2*PI) range of the lathed section -// 2*pi is a closed lathe, less than 2PI is a portion. -THREE.LatheGeometry = function ( points, segments, phiStart, phiLength ) { - - THREE.Geometry.call( this ); - - segments = segments || 12; - phiStart = phiStart || 0; - phiLength = phiLength || 2 * Math.PI; - - var inversePointLength = 1.0 / ( points.length - 1 ); - var inverseSegments = 1.0 / segments; - - for ( var i = 0, il = segments; i <= il; i ++ ) { - - var phi = phiStart + i * inverseSegments * phiLength; - - var c = Math.cos( phi ), - s = Math.sin( phi ); - - for ( var j = 0, jl = points.length; j < jl; j ++ ) { - - var pt = points[ j ]; - - var vertex = new THREE.Vector3(); - - vertex.x = c * pt.x - s * pt.y; - vertex.y = s * pt.x + c * pt.y; - vertex.z = pt.z; - - this.vertices.push( vertex ); - - } - - } - - var np = points.length; - - for ( var i = 0, il = segments; i < il; i ++ ) { - - for ( var j = 0, jl = points.length - 1; j < jl; j ++ ) { - - var base = j + np * i; - var a = base; - var b = base + np; - var c = base + 1 + np; - var d = base + 1; - - var u0 = i * inverseSegments; - var v0 = j * inversePointLength; - var u1 = u0 + inverseSegments; - var v1 = v0 + inversePointLength; - - this.faces.push( new THREE.Face3( a, b, d ) ); - - this.faceVertexUvs[ 0 ].push( [ - - new THREE.Vector2( u0, v0 ), - new THREE.Vector2( u1, v0 ), - new THREE.Vector2( u0, v1 ) - - ] ); - - this.faces.push( new THREE.Face3( b, c, d ) ); - - this.faceVertexUvs[ 0 ].push( [ - - new THREE.Vector2( u1, v0 ), - new THREE.Vector2( u1, v1 ), - new THREE.Vector2( u0, v1 ) - - ] ); - - - } - - } - - this.mergeVertices(); - this.computeFaceNormals(); - this.computeVertexNormals(); - -}; - -THREE.LatheGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author mrdoob / http://mrdoob.com/ - * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as - */ - -THREE.PlaneGeometry = function ( width, height, widthSegments, heightSegments ) { - - THREE.Geometry.call( this ); - - this.parameters = { - width: width, - height: height, - widthSegments: widthSegments, - heightSegments: heightSegments - }; - - var ix, iz; - var width_half = width / 2; - var height_half = height / 2; - - var gridX = widthSegments || 1; - var gridZ = heightSegments || 1; - - var gridX1 = gridX + 1; - var gridZ1 = gridZ + 1; - - var segment_width = width / gridX; - var segment_height = height / gridZ; - - var normal = new THREE.Vector3( 0, 0, 1 ); - - for ( iz = 0; iz < gridZ1; iz ++ ) { - - var y = iz * segment_height - height_half; - - for ( ix = 0; ix < gridX1; ix ++ ) { - - var x = ix * segment_width - width_half; - - this.vertices.push( new THREE.Vector3( x, - y, 0 ) ); - - } - - } - - for ( iz = 0; iz < gridZ; iz ++ ) { - - for ( ix = 0; ix < gridX; ix ++ ) { - - var a = ix + gridX1 * iz; - var b = ix + gridX1 * ( iz + 1 ); - var c = ( ix + 1 ) + gridX1 * ( iz + 1 ); - var d = ( ix + 1 ) + gridX1 * iz; - - var uva = new THREE.Vector2( ix / gridX, 1 - iz / gridZ ); - var uvb = new THREE.Vector2( ix / gridX, 1 - ( iz + 1 ) / gridZ ); - var uvc = new THREE.Vector2( ( ix + 1 ) / gridX, 1 - ( iz + 1 ) / gridZ ); - var uvd = new THREE.Vector2( ( ix + 1 ) / gridX, 1 - iz / gridZ ); - - var face = new THREE.Face3( a, b, d ); - face.normal.copy( normal ); - face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() ); - - this.faces.push( face ); - this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] ); - - face = new THREE.Face3( b, c, d ); - face.normal.copy( normal ); - face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() ); - - this.faces.push( face ); - this.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] ); - - } - - } - -}; - -THREE.PlaneGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author Kaleb Murphy - */ - -THREE.RingGeometry = function ( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { - - THREE.Geometry.call( this ); - - innerRadius = innerRadius || 0; - outerRadius = outerRadius || 50; - - thetaStart = thetaStart !== undefined ? thetaStart : 0; - thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; - - thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8; - phiSegments = phiSegments !== undefined ? Math.max( 3, phiSegments ) : 8; - - var i, o, uvs = [], radius = innerRadius, radiusStep = ( ( outerRadius - innerRadius ) / phiSegments ); - - for ( i = 0; i <= phiSegments; i ++ ) { // concentric circles inside ring - - for ( o = 0; o <= thetaSegments; o ++ ) { // number of segments per circle - - var vertex = new THREE.Vector3(); - var segment = thetaStart + o / thetaSegments * thetaLength; - - vertex.x = radius * Math.cos( segment ); - vertex.y = radius * Math.sin( segment ); - - this.vertices.push( vertex ); - uvs.push( new THREE.Vector2( ( vertex.x / outerRadius + 1 ) / 2, ( vertex.y / outerRadius + 1 ) / 2 ) ); - } - - radius += radiusStep; - - } - - var n = new THREE.Vector3( 0, 0, 1 ); - - for ( i = 0; i < phiSegments; i ++ ) { // concentric circles inside ring - - var thetaSegment = i * thetaSegments; - - for ( o = 0; o <= thetaSegments; o ++ ) { // number of segments per circle - - var segment = o + thetaSegment; - - var v1 = segment + i; - var v2 = segment + thetaSegments + i; - var v3 = segment + thetaSegments + 1 + i; - - this.faces.push( new THREE.Face3( v1, v2, v3, [ n.clone(), n.clone(), n.clone() ] ) ); - this.faceVertexUvs[ 0 ].push( [ uvs[ v1 ].clone(), uvs[ v2 ].clone(), uvs[ v3 ].clone() ]); - - v1 = segment + i; - v2 = segment + thetaSegments + 1 + i; - v3 = segment + 1 + i; - - this.faces.push( new THREE.Face3( v1, v2, v3, [ n.clone(), n.clone(), n.clone() ] ) ); - this.faceVertexUvs[ 0 ].push( [ uvs[ v1 ].clone(), uvs[ v2 ].clone(), uvs[ v3 ].clone() ]); - - } - } - - this.computeFaceNormals(); - - this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius ); - -}; - -THREE.RingGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.SphereGeometry = function ( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { - - THREE.Geometry.call( this ); - - this.parameters = { - radius: radius, - widthSegments: widthSegments, - heightSegments: heightSegments, - phiStart: phiStart, - phiLength: phiLength, - thetaStart: thetaStart, - thetaLength: thetaLength - }; - - radius = radius || 50; - - widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 ); - heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 ); - - phiStart = phiStart !== undefined ? phiStart : 0; - phiLength = phiLength !== undefined ? phiLength : Math.PI * 2; - - thetaStart = thetaStart !== undefined ? thetaStart : 0; - thetaLength = thetaLength !== undefined ? thetaLength : Math.PI; - - var x, y, vertices = [], uvs = []; - - for ( y = 0; y <= heightSegments; y ++ ) { - - var verticesRow = []; - var uvsRow = []; - - for ( x = 0; x <= widthSegments; x ++ ) { - - var u = x / widthSegments; - var v = y / heightSegments; - - var vertex = new THREE.Vector3(); - vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); - vertex.y = radius * Math.cos( thetaStart + v * thetaLength ); - vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); - - this.vertices.push( vertex ); - - verticesRow.push( this.vertices.length - 1 ); - uvsRow.push( new THREE.Vector2( u, 1 - v ) ); - - } - - vertices.push( verticesRow ); - uvs.push( uvsRow ); - - } - - for ( y = 0; y < heightSegments; y ++ ) { - - for ( x = 0; x < widthSegments; x ++ ) { - - var v1 = vertices[ y ][ x + 1 ]; - var v2 = vertices[ y ][ x ]; - var v3 = vertices[ y + 1 ][ x ]; - var v4 = vertices[ y + 1 ][ x + 1 ]; - - var n1 = this.vertices[ v1 ].clone().normalize(); - var n2 = this.vertices[ v2 ].clone().normalize(); - var n3 = this.vertices[ v3 ].clone().normalize(); - var n4 = this.vertices[ v4 ].clone().normalize(); - - var uv1 = uvs[ y ][ x + 1 ].clone(); - var uv2 = uvs[ y ][ x ].clone(); - var uv3 = uvs[ y + 1 ][ x ].clone(); - var uv4 = uvs[ y + 1 ][ x + 1 ].clone(); - - if ( Math.abs( this.vertices[ v1 ].y ) === radius ) { - - uv1.x = ( uv1.x + uv2.x ) / 2; - this.faces.push( new THREE.Face3( v1, v3, v4, [ n1, n3, n4 ] ) ); - this.faceVertexUvs[ 0 ].push( [ uv1, uv3, uv4 ] ); - - } else if ( Math.abs( this.vertices[ v3 ].y ) === radius ) { - - uv3.x = ( uv3.x + uv4.x ) / 2; - this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) ); - this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] ); - - } else { - - this.faces.push( new THREE.Face3( v1, v2, v4, [ n1, n2, n4 ] ) ); - this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv4 ] ); - - this.faces.push( new THREE.Face3( v2, v3, v4, [ n2.clone(), n3, n4.clone() ] ) ); - this.faceVertexUvs[ 0 ].push( [ uv2.clone(), uv3, uv4.clone() ] ); - - } - - } - - } - - this.computeFaceNormals(); - - this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius ); - -}; - -THREE.SphereGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author zz85 / http://www.lab4games.net/zz85/blog - * @author alteredq / http://alteredqualia.com/ - * - * For creating 3D text geometry in three.js - * - * Text = 3D Text - * - * parameters = { - * size: , // size of the text - * height: , // thickness to extrude text - * curveSegments: , // number of points on the curves - * - * font: , // font name - * weight: , // font weight (normal, bold) - * style: , // font style (normal, italics) - * - * bevelEnabled: , // turn on bevel - * bevelThickness: , // how deep into text bevel goes - * bevelSize: , // how far from text outline is bevel - * } - * - */ - -/* Usage Examples - - // TextGeometry wrapper - - var text3d = new TextGeometry( text, options ); - - // Complete manner - - var textShapes = THREE.FontUtils.generateShapes( text, options ); - var text3d = new ExtrudeGeometry( textShapes, options ); - -*/ - - -THREE.TextGeometry = function ( text, parameters ) { - - parameters = parameters || {}; - - var textShapes = THREE.FontUtils.generateShapes( text, parameters ); - - // translate parameters to ExtrudeGeometry API - - parameters.amount = parameters.height !== undefined ? parameters.height : 50; - - // defaults - - if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10; - if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8; - if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false; - - THREE.ExtrudeGeometry.call( this, textShapes, parameters ); - -}; - -THREE.TextGeometry.prototype = Object.create( THREE.ExtrudeGeometry.prototype ); - -/** - * @author oosmoxiecode - * @author mrdoob / http://mrdoob.com/ - * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888 - */ - -THREE.TorusGeometry = function ( radius, tube, radialSegments, tubularSegments, arc ) { - - THREE.Geometry.call( this ); - - this.parameters = { - radius: radius, - tube: tube, - radialSegments: radialSegments, - tubularSegments: tubularSegments, - arc: arc - }; - - radius = radius || 100; - tube = tube || 40; - radialSegments = radialSegments || 8; - tubularSegments = tubularSegments || 6; - arc = arc || Math.PI * 2; - - var center = new THREE.Vector3(), uvs = [], normals = []; - - for ( var j = 0; j <= radialSegments; j ++ ) { - - for ( var i = 0; i <= tubularSegments; i ++ ) { - - var u = i / tubularSegments * arc; - var v = j / radialSegments * Math.PI * 2; - - center.x = radius * Math.cos( u ); - center.y = radius * Math.sin( u ); - - var vertex = new THREE.Vector3(); - vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u ); - vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u ); - vertex.z = tube * Math.sin( v ); - - this.vertices.push( vertex ); - - uvs.push( new THREE.Vector2( i / tubularSegments, j / radialSegments ) ); - normals.push( vertex.clone().sub( center ).normalize() ); - - } - - } - - for ( var j = 1; j <= radialSegments; j ++ ) { - - for ( var i = 1; i <= tubularSegments; i ++ ) { - - var a = ( tubularSegments + 1 ) * j + i - 1; - var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1; - var c = ( tubularSegments + 1 ) * ( j - 1 ) + i; - var d = ( tubularSegments + 1 ) * j + i; - - var face = new THREE.Face3( a, b, d, [ normals[ a ].clone(), normals[ b ].clone(), normals[ d ].clone() ] ); - this.faces.push( face ); - this.faceVertexUvs[ 0 ].push( [ uvs[ a ].clone(), uvs[ b ].clone(), uvs[ d ].clone() ] ); - - face = new THREE.Face3( b, c, d, [ normals[ b ].clone(), normals[ c ].clone(), normals[ d ].clone() ] ); - this.faces.push( face ); - this.faceVertexUvs[ 0 ].push( [ uvs[ b ].clone(), uvs[ c ].clone(), uvs[ d ].clone() ] ); - - } - - } - - this.computeFaceNormals(); - -}; - -THREE.TorusGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author oosmoxiecode - * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473 - */ - -THREE.TorusKnotGeometry = function ( radius, tube, radialSegments, tubularSegments, p, q, heightScale ) { - - THREE.Geometry.call( this ); - - this.parameters = { - radius: radius, - tube: tube, - radialSegments: radialSegments, - tubularSegments: tubularSegments, - p: p, - q: q, - heightScale: heightScale - }; - - radius = radius || 100; - tube = tube || 40; - radialSegments = radialSegments || 64; - tubularSegments = tubularSegments || 8; - p = p || 2; - q = q || 3; - heightScale = heightScale || 1; - - var grid = new Array( radialSegments ); - var tang = new THREE.Vector3(); - var n = new THREE.Vector3(); - var bitan = new THREE.Vector3(); - - for ( var i = 0; i < radialSegments; ++ i ) { - - grid[ i ] = new Array( tubularSegments ); - var u = i / radialSegments * 2 * p * Math.PI; - var p1 = getPos( u, q, p, radius, heightScale ); - var p2 = getPos( u + 0.01, q, p, radius, heightScale ); - tang.subVectors( p2, p1 ); - n.addVectors( p2, p1 ); - - bitan.crossVectors( tang, n ); - n.crossVectors( bitan, tang ); - bitan.normalize(); - n.normalize(); - - for ( var j = 0; j < tubularSegments; ++ j ) { - - var v = j / tubularSegments * 2 * Math.PI; - var cx = - tube * Math.cos( v ); // TODO: Hack: Negating it so it faces outside. - var cy = tube * Math.sin( v ); - - var pos = new THREE.Vector3(); - pos.x = p1.x + cx * n.x + cy * bitan.x; - pos.y = p1.y + cx * n.y + cy * bitan.y; - pos.z = p1.z + cx * n.z + cy * bitan.z; - - grid[ i ][ j ] = this.vertices.push( pos ) - 1; - - } - - } - - for ( var i = 0; i < radialSegments; ++ i ) { - - for ( var j = 0; j < tubularSegments; ++ j ) { - - var ip = ( i + 1 ) % radialSegments; - var jp = ( j + 1 ) % tubularSegments; - - var a = grid[ i ][ j ]; - var b = grid[ ip ][ j ]; - var c = grid[ ip ][ jp ]; - var d = grid[ i ][ jp ]; - - var uva = new THREE.Vector2( i / radialSegments, j / tubularSegments ); - var uvb = new THREE.Vector2( ( i + 1 ) / radialSegments, j / tubularSegments ); - var uvc = new THREE.Vector2( ( i + 1 ) / radialSegments, ( j + 1 ) / tubularSegments ); - var uvd = new THREE.Vector2( i / radialSegments, ( j + 1 ) / tubularSegments ); - - this.faces.push( new THREE.Face3( a, b, d ) ); - this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] ); - - this.faces.push( new THREE.Face3( b, c, d ) ); - this.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] ); - - } - } - - this.computeFaceNormals(); - this.computeVertexNormals(); - - function getPos( u, in_q, in_p, radius, heightScale ) { - - var cu = Math.cos( u ); - var su = Math.sin( u ); - var quOverP = in_q / in_p * u; - var cs = Math.cos( quOverP ); - - var tx = radius * ( 2 + cs ) * 0.5 * cu; - var ty = radius * ( 2 + cs ) * su * 0.5; - var tz = heightScale * radius * Math.sin( quOverP ) * 0.5; - - return new THREE.Vector3( tx, ty, tz ); - - } - -}; - -THREE.TorusKnotGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author WestLangley / https://github.com/WestLangley - * @author zz85 / https://github.com/zz85 - * @author miningold / https://github.com/miningold - * - * Modified from the TorusKnotGeometry by @oosmoxiecode - * - * Creates a tube which extrudes along a 3d spline - * - * Uses parallel transport frames as described in - * http://www.cs.indiana.edu/pub/techreports/TR425.pdf - */ - -THREE.TubeGeometry = function ( path, segments, radius, radialSegments, closed ) { - - THREE.Geometry.call( this ); - - this.parameters = { - path: path, - segments: segments, - radius: radius, - radialSegments: radialSegments, - closed: closed - }; - - segments = segments || 64; - radius = radius || 1; - radialSegments = radialSegments || 8; - closed = closed || false; - - var grid = []; - - var scope = this, - - tangent, - normal, - binormal, - - numpoints = segments + 1, - - x, y, z, - tx, ty, tz, - u, v, - - cx, cy, - pos, pos2 = new THREE.Vector3(), - i, j, - ip, jp, - a, b, c, d, - uva, uvb, uvc, uvd; - - var frames = new THREE.TubeGeometry.FrenetFrames( path, segments, closed ), - tangents = frames.tangents, - normals = frames.normals, - binormals = frames.binormals; - - // proxy internals - this.tangents = tangents; - this.normals = normals; - this.binormals = binormals; - - function vert( x, y, z ) { - - return scope.vertices.push( new THREE.Vector3( x, y, z ) ) - 1; - - } - - // consruct the grid - - for ( i = 0; i < numpoints; i++ ) { - - grid[ i ] = []; - - u = i / ( numpoints - 1 ); - - pos = path.getPointAt( u ); - - tangent = tangents[ i ]; - normal = normals[ i ]; - binormal = binormals[ i ]; - - for ( j = 0; j < radialSegments; j++ ) { - - v = j / radialSegments * 2 * Math.PI; - - cx = -radius * Math.cos( v ); // TODO: Hack: Negating it so it faces outside. - cy = radius * Math.sin( v ); - - pos2.copy( pos ); - pos2.x += cx * normal.x + cy * binormal.x; - pos2.y += cx * normal.y + cy * binormal.y; - pos2.z += cx * normal.z + cy * binormal.z; - - grid[ i ][ j ] = vert( pos2.x, pos2.y, pos2.z ); - - } - } - - - // construct the mesh - - for ( i = 0; i < segments; i++ ) { - - for ( j = 0; j < radialSegments; j++ ) { - - ip = ( closed ) ? (i + 1) % segments : i + 1; - jp = (j + 1) % radialSegments; - - a = grid[ i ][ j ]; // *** NOT NECESSARILY PLANAR ! *** - b = grid[ ip ][ j ]; - c = grid[ ip ][ jp ]; - d = grid[ i ][ jp ]; - - uva = new THREE.Vector2( i / segments, j / radialSegments ); - uvb = new THREE.Vector2( ( i + 1 ) / segments, j / radialSegments ); - uvc = new THREE.Vector2( ( i + 1 ) / segments, ( j + 1 ) / radialSegments ); - uvd = new THREE.Vector2( i / segments, ( j + 1 ) / radialSegments ); - - this.faces.push( new THREE.Face3( a, b, d ) ); - this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] ); - - this.faces.push( new THREE.Face3( b, c, d ) ); - this.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] ); - - } - } - - this.computeFaceNormals(); - this.computeVertexNormals(); - -}; - -THREE.TubeGeometry.prototype = Object.create( THREE.Geometry.prototype ); - - -// For computing of Frenet frames, exposing the tangents, normals and binormals the spline -THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) { - - var tangent = new THREE.Vector3(), - normal = new THREE.Vector3(), - binormal = new THREE.Vector3(), - - tangents = [], - normals = [], - binormals = [], - - vec = new THREE.Vector3(), - mat = new THREE.Matrix4(), - - numpoints = segments + 1, - theta, - epsilon = 0.0001, - smallest, - - tx, ty, tz, - i, u, v; - - - // expose internals - this.tangents = tangents; - this.normals = normals; - this.binormals = binormals; - - // compute the tangent vectors for each segment on the path - - for ( i = 0; i < numpoints; i++ ) { - - u = i / ( numpoints - 1 ); - - tangents[ i ] = path.getTangentAt( u ); - tangents[ i ].normalize(); - - } - - initialNormal3(); - - function initialNormal1(lastBinormal) { - // fixed start binormal. Has dangers of 0 vectors - normals[ 0 ] = new THREE.Vector3(); - binormals[ 0 ] = new THREE.Vector3(); - if (lastBinormal===undefined) lastBinormal = new THREE.Vector3( 0, 0, 1 ); - normals[ 0 ].crossVectors( lastBinormal, tangents[ 0 ] ).normalize(); - binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] ).normalize(); - } - - function initialNormal2() { - - // This uses the Frenet-Serret formula for deriving binormal - var t2 = path.getTangentAt( epsilon ); - - normals[ 0 ] = new THREE.Vector3().subVectors( t2, tangents[ 0 ] ).normalize(); - binormals[ 0 ] = new THREE.Vector3().crossVectors( tangents[ 0 ], normals[ 0 ] ); - - normals[ 0 ].crossVectors( binormals[ 0 ], tangents[ 0 ] ).normalize(); // last binormal x tangent - binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] ).normalize(); - - } - - function initialNormal3() { - // select an initial normal vector perpenicular to the first tangent vector, - // and in the direction of the smallest tangent xyz component - - normals[ 0 ] = new THREE.Vector3(); - binormals[ 0 ] = new THREE.Vector3(); - smallest = Number.MAX_VALUE; - tx = Math.abs( tangents[ 0 ].x ); - ty = Math.abs( tangents[ 0 ].y ); - tz = Math.abs( tangents[ 0 ].z ); - - if ( tx <= smallest ) { - smallest = tx; - normal.set( 1, 0, 0 ); - } - - if ( ty <= smallest ) { - smallest = ty; - normal.set( 0, 1, 0 ); - } - - if ( tz <= smallest ) { - normal.set( 0, 0, 1 ); - } - - vec.crossVectors( tangents[ 0 ], normal ).normalize(); - - normals[ 0 ].crossVectors( tangents[ 0 ], vec ); - binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] ); - } - - - // compute the slowly-varying normal and binormal vectors for each segment on the path - - for ( i = 1; i < numpoints; i++ ) { - - normals[ i ] = normals[ i-1 ].clone(); - - binormals[ i ] = binormals[ i-1 ].clone(); - - vec.crossVectors( tangents[ i-1 ], tangents[ i ] ); - - if ( vec.length() > epsilon ) { - - vec.normalize(); - - theta = Math.acos( THREE.Math.clamp( tangents[ i-1 ].dot( tangents[ i ] ), -1, 1 ) ); // clamp for floating pt errors - - normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) ); - - } - - binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); - - } - - - // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same - - if ( closed ) { - - theta = Math.acos( THREE.Math.clamp( normals[ 0 ].dot( normals[ numpoints-1 ] ), -1, 1 ) ); - theta /= ( numpoints - 1 ); - - if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ numpoints-1 ] ) ) > 0 ) { - - theta = -theta; - - } - - for ( i = 1; i < numpoints; i++ ) { - - // twist a little... - normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) ); - binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); - - } - - } -}; - -/** - * @author clockworkgeek / https://github.com/clockworkgeek - * @author timothypratley / https://github.com/timothypratley - * @author WestLangley / http://github.com/WestLangley -*/ - -THREE.PolyhedronGeometry = function ( vertices, indices, radius, detail ) { - - THREE.Geometry.call( this ); - - radius = radius || 1; - detail = detail || 0; - - var that = this; - - for ( var i = 0, l = vertices.length; i < l; i += 3 ) { - - prepare( new THREE.Vector3( vertices[ i ], vertices[ i + 1 ], vertices[ i + 2 ] ) ); - - } - - var midpoints = [], p = this.vertices; - - var faces = []; - - for ( var i = 0, j = 0, l = indices.length; i < l; i += 3, j ++ ) { - - var v1 = p[ indices[ i ] ]; - var v2 = p[ indices[ i + 1 ] ]; - var v3 = p[ indices[ i + 2 ] ]; - - faces[ j ] = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.clone(), v2.clone(), v3.clone() ] ); - - } - - var centroid = new THREE.Vector3(); - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - subdivide( faces[ i ], detail ); - - } - - - // Handle case when face straddles the seam - - for ( var i = 0, l = this.faceVertexUvs[ 0 ].length; i < l; i ++ ) { - - var uvs = this.faceVertexUvs[ 0 ][ i ]; - - var x0 = uvs[ 0 ].x; - var x1 = uvs[ 1 ].x; - var x2 = uvs[ 2 ].x; - - var max = Math.max( x0, Math.max( x1, x2 ) ); - var min = Math.min( x0, Math.min( x1, x2 ) ); - - if ( max > 0.9 && min < 0.1 ) { // 0.9 is somewhat arbitrary - - if ( x0 < 0.2 ) uvs[ 0 ].x += 1; - if ( x1 < 0.2 ) uvs[ 1 ].x += 1; - if ( x2 < 0.2 ) uvs[ 2 ].x += 1; - - } - - } - - - // Apply radius - - for ( var i = 0, l = this.vertices.length; i < l; i ++ ) { - - this.vertices[ i ].multiplyScalar( radius ); - - } - - - // Merge vertices - - this.mergeVertices(); - - this.computeFaceNormals(); - - this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius ); - - - // Project vector onto sphere's surface - - function prepare( vector ) { - - var vertex = vector.normalize().clone(); - vertex.index = that.vertices.push( vertex ) - 1; - - // Texture coords are equivalent to map coords, calculate angle and convert to fraction of a circle. - - var u = azimuth( vector ) / 2 / Math.PI + 0.5; - var v = inclination( vector ) / Math.PI + 0.5; - vertex.uv = new THREE.Vector2( u, 1 - v ); - - return vertex; - - } - - - // Approximate a curved face with recursively sub-divided triangles. - - function make( v1, v2, v3 ) { - - var face = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.clone(), v2.clone(), v3.clone() ] ); - that.faces.push( face ); - - centroid.copy( v1 ).add( v2 ).add( v3 ).divideScalar( 3 ); - - var azi = azimuth( centroid ); - - that.faceVertexUvs[ 0 ].push( [ - correctUV( v1.uv, v1, azi ), - correctUV( v2.uv, v2, azi ), - correctUV( v3.uv, v3, azi ) - ] ); - - } - - - // Analytically subdivide a face to the required detail level. - - function subdivide( face, detail ) { - - var cols = Math.pow(2, detail); - var cells = Math.pow(4, detail); - var a = prepare( that.vertices[ face.a ] ); - var b = prepare( that.vertices[ face.b ] ); - var c = prepare( that.vertices[ face.c ] ); - var v = []; - - // Construct all of the vertices for this subdivision. - - for ( var i = 0 ; i <= cols; i ++ ) { - - v[ i ] = []; - - var aj = prepare( a.clone().lerp( c, i / cols ) ); - var bj = prepare( b.clone().lerp( c, i / cols ) ); - var rows = cols - i; - - for ( var j = 0; j <= rows; j ++) { - - if ( j == 0 && i == cols ) { - - v[ i ][ j ] = aj; - - } else { - - v[ i ][ j ] = prepare( aj.clone().lerp( bj, j / rows ) ); - - } - - } - - } - - // Construct all of the faces. - - for ( var i = 0; i < cols ; i ++ ) { - - for ( var j = 0; j < 2 * (cols - i) - 1; j ++ ) { - - var k = Math.floor( j / 2 ); - - if ( j % 2 == 0 ) { - - make( - v[ i ][ k + 1], - v[ i + 1 ][ k ], - v[ i ][ k ] - ); - - } else { - - make( - v[ i ][ k + 1 ], - v[ i + 1][ k + 1], - v[ i + 1 ][ k ] - ); - - } - - } - - } - - } - - - // Angle around the Y axis, counter-clockwise when looking from above. - - function azimuth( vector ) { - - return Math.atan2( vector.z, -vector.x ); - - } - - - // Angle above the XZ plane. - - function inclination( vector ) { - - return Math.atan2( -vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) ); - - } - - - // Texture fixing helper. Spheres have some odd behaviours. - - function correctUV( uv, vector, azimuth ) { - - if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) uv = new THREE.Vector2( uv.x - 1, uv.y ); - if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) uv = new THREE.Vector2( azimuth / 2 / Math.PI + 0.5, uv.y ); - return uv.clone(); - - } - - -}; - -THREE.PolyhedronGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author timothypratley / https://github.com/timothypratley - */ - -THREE.IcosahedronGeometry = function ( radius, detail ) { - - this.parameters = { - radius: radius, - detail: detail - }; - - var t = ( 1 + Math.sqrt( 5 ) ) / 2; - - var vertices = [ - -1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, - 0, -1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, - t, 0, -1, t, 0, 1, -t, 0, -1, -t, 0, 1 - ]; - - var indices = [ - 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, - 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, - 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, - 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1 - ]; - - THREE.PolyhedronGeometry.call( this, vertices, indices, radius, detail ); - -}; - -THREE.IcosahedronGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author timothypratley / https://github.com/timothypratley - */ - -THREE.OctahedronGeometry = function ( radius, detail ) { - - this.parameters = { - radius: radius, - detail: detail - }; - - var vertices = [ - 1, 0, 0, -1, 0, 0, 0, 1, 0, 0,-1, 0, 0, 0, 1, 0, 0,-1 - ]; - - var indices = [ - 0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2 - ]; - - THREE.PolyhedronGeometry.call( this, vertices, indices, radius, detail ); -}; - -THREE.OctahedronGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author timothypratley / https://github.com/timothypratley - */ - -THREE.TetrahedronGeometry = function ( radius, detail ) { - - var vertices = [ - 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1 - ]; - - var indices = [ - 2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1 - ]; - - THREE.PolyhedronGeometry.call( this, vertices, indices, radius, detail ); - -}; - -THREE.TetrahedronGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author zz85 / https://github.com/zz85 - * Parametric Surfaces Geometry - * based on the brilliant article by @prideout http://prideout.net/blog/?p=44 - * - * new THREE.ParametricGeometry( parametricFunction, uSegments, ySegements ); - * - */ - -THREE.ParametricGeometry = function ( func, slices, stacks ) { - - THREE.Geometry.call( this ); - - var verts = this.vertices; - var faces = this.faces; - var uvs = this.faceVertexUvs[ 0 ]; - - var i, il, j, p; - var u, v; - - var stackCount = stacks + 1; - var sliceCount = slices + 1; - - for ( i = 0; i <= stacks; i ++ ) { - - v = i / stacks; - - for ( j = 0; j <= slices; j ++ ) { - - u = j / slices; - - p = func( u, v ); - verts.push( p ); - - } - } - - var a, b, c, d; - var uva, uvb, uvc, uvd; - - for ( i = 0; i < stacks; i ++ ) { - - for ( j = 0; j < slices; j ++ ) { - - a = i * sliceCount + j; - b = i * sliceCount + j + 1; - c = (i + 1) * sliceCount + j + 1; - d = (i + 1) * sliceCount + j; - - uva = new THREE.Vector2( j / slices, i / stacks ); - uvb = new THREE.Vector2( ( j + 1 ) / slices, i / stacks ); - uvc = new THREE.Vector2( ( j + 1 ) / slices, ( i + 1 ) / stacks ); - uvd = new THREE.Vector2( j / slices, ( i + 1 ) / stacks ); - - faces.push( new THREE.Face3( a, b, d ) ); - uvs.push( [ uva, uvb, uvd ] ); - - faces.push( new THREE.Face3( b, c, d ) ); - uvs.push( [ uvb.clone(), uvc, uvd.clone() ] ); - - } - - } - - // console.log(this); - - // magic bullet - // var diff = this.mergeVertices(); - // console.log('removed ', diff, ' vertices by merging'); - - this.computeFaceNormals(); - this.computeVertexNormals(); - -}; - -THREE.ParametricGeometry.prototype = Object.create( THREE.Geometry.prototype ); - -/** - * @author sroucheray / http://sroucheray.org/ - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.AxisHelper = function ( size ) { - - size = size || 1; - - var geometry = new THREE.Geometry(); - - geometry.vertices.push( - new THREE.Vector3(), new THREE.Vector3( size, 0, 0 ), - new THREE.Vector3(), new THREE.Vector3( 0, size, 0 ), - new THREE.Vector3(), new THREE.Vector3( 0, 0, size ) - ); - - geometry.colors.push( - new THREE.Color( 0xff0000 ), new THREE.Color( 0xffaa00 ), - new THREE.Color( 0x00ff00 ), new THREE.Color( 0xaaff00 ), - new THREE.Color( 0x0000ff ), new THREE.Color( 0x00aaff ) - ); - - var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } ); - - THREE.Line.call( this, geometry, material, THREE.LinePieces ); - -}; - -THREE.AxisHelper.prototype = Object.create( THREE.Line.prototype ); - -/** - * @author WestLangley / http://github.com/WestLangley - * @author zz85 / http://github.com/zz85 - * @author bhouston / http://exocortex.com - * - * Creates an arrow for visualizing directions - * - * Parameters: - * dir - Vector3 - * origin - Vector3 - * length - Number - * color - color in hex value - * headLength - Number - * headWidth - Number - */ - -THREE.ArrowHelper = function ( dir, origin, length, color, headLength, headWidth ) { - - // dir is assumed to be normalized - - THREE.Object3D.call( this ); - - if ( color === undefined ) color = 0xffff00; - if ( length === undefined ) length = 1; - if ( headLength === undefined ) headLength = 0.2 * length; - if ( headWidth === undefined ) headWidth = 0.2 * headLength; - - this.position = origin; - - var lineGeometry = new THREE.Geometry(); - lineGeometry.vertices.push( new THREE.Vector3( 0, 0, 0 ) ); - lineGeometry.vertices.push( new THREE.Vector3( 0, 1, 0 ) ); - - this.line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color: color } ) ); - this.line.matrixAutoUpdate = false; - this.add( this.line ); - - var coneGeometry = new THREE.CylinderGeometry( 0, 0.5, 1, 5, 1 ); - coneGeometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, - 0.5, 0 ) ); - - this.cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color: color } ) ); - this.cone.matrixAutoUpdate = false; - this.add( this.cone ); - - this.setDirection( dir ); - this.setLength( length, headLength, headWidth ); - -}; - -THREE.ArrowHelper.prototype = Object.create( THREE.Object3D.prototype ); - -THREE.ArrowHelper.prototype.setDirection = function () { - - var axis = new THREE.Vector3(); - var radians; - - return function ( dir ) { - - // dir is assumed to be normalized - - if ( dir.y > 0.99999 ) { - - this.quaternion.set( 0, 0, 0, 1 ); - - } else if ( dir.y < - 0.99999 ) { - - this.quaternion.set( 1, 0, 0, 0 ); - - } else { - - axis.set( dir.z, 0, - dir.x ).normalize(); - - radians = Math.acos( dir.y ); - - this.quaternion.setFromAxisAngle( axis, radians ); - - } - - }; - -}(); - -THREE.ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) { - - if ( headLength === undefined ) headLength = 0.2 * length; - if ( headWidth === undefined ) headWidth = 0.2 * headLength; - - this.line.scale.set( 1, length, 1 ); - this.line.updateMatrix(); - - this.cone.scale.set( headWidth, headLength, headWidth ); - this.cone.position.y = length; - this.cone.updateMatrix(); - -}; - -THREE.ArrowHelper.prototype.setColor = function ( color ) { - - this.line.material.color.set( color ); - this.cone.material.color.set( color ); - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.BoxHelper = function ( object ) { - - // 5____4 - // 1/___0/| - // | 6__|_7 - // 2/___3/ - - var vertices = [ - new THREE.Vector3( 1, 1, 1 ), - new THREE.Vector3( - 1, 1, 1 ), - new THREE.Vector3( - 1, - 1, 1 ), - new THREE.Vector3( 1, - 1, 1 ), - - new THREE.Vector3( 1, 1, - 1 ), - new THREE.Vector3( - 1, 1, - 1 ), - new THREE.Vector3( - 1, - 1, - 1 ), - new THREE.Vector3( 1, - 1, - 1 ) - ]; - - this.vertices = vertices; - - // TODO: Wouldn't be nice if Line had .segments? - - var geometry = new THREE.Geometry(); - geometry.vertices.push( - vertices[ 0 ], vertices[ 1 ], - vertices[ 1 ], vertices[ 2 ], - vertices[ 2 ], vertices[ 3 ], - vertices[ 3 ], vertices[ 0 ], - - vertices[ 4 ], vertices[ 5 ], - vertices[ 5 ], vertices[ 6 ], - vertices[ 6 ], vertices[ 7 ], - vertices[ 7 ], vertices[ 4 ], - - vertices[ 0 ], vertices[ 4 ], - vertices[ 1 ], vertices[ 5 ], - vertices[ 2 ], vertices[ 6 ], - vertices[ 3 ], vertices[ 7 ] - ); - - THREE.Line.call( this, geometry, new THREE.LineBasicMaterial( { color: 0xffff00 } ), THREE.LinePieces ); - - if ( object !== undefined ) { - - this.update( object ); - - } - -}; - -THREE.BoxHelper.prototype = Object.create( THREE.Line.prototype ); - -THREE.BoxHelper.prototype.update = function ( object ) { - - var geometry = object.geometry; - - if ( geometry.boundingBox === null ) { - - geometry.computeBoundingBox(); - - } - - var min = geometry.boundingBox.min; - var max = geometry.boundingBox.max; - var vertices = this.vertices; - - vertices[ 0 ].set( max.x, max.y, max.z ); - vertices[ 1 ].set( min.x, max.y, max.z ); - vertices[ 2 ].set( min.x, min.y, max.z ); - vertices[ 3 ].set( max.x, min.y, max.z ); - vertices[ 4 ].set( max.x, max.y, min.z ); - vertices[ 5 ].set( min.x, max.y, min.z ); - vertices[ 6 ].set( min.x, min.y, min.z ); - vertices[ 7 ].set( max.x, min.y, min.z ); - - this.geometry.computeBoundingSphere(); - this.geometry.verticesNeedUpdate = true; - - this.matrixAutoUpdate = false; - this.matrixWorld = object.matrixWorld; - -}; - -/** - * @author WestLangley / http://github.com/WestLangley - */ - -// a helper to show the world-axis-aligned bounding box for an object - -THREE.BoundingBoxHelper = function ( object, hex ) { - - var color = ( hex !== undefined ) ? hex : 0x888888; - - this.object = object; - - this.box = new THREE.Box3(); - - THREE.Mesh.call( this, new THREE.BoxGeometry( 1, 1, 1 ), new THREE.MeshBasicMaterial( { color: color, wireframe: true } ) ); - -}; - -THREE.BoundingBoxHelper.prototype = Object.create( THREE.Mesh.prototype ); - -THREE.BoundingBoxHelper.prototype.update = function () { - - this.box.setFromObject( this.object ); - - this.box.size( this.scale ); - - this.box.center( this.position ); - -}; - -/** - * @author alteredq / http://alteredqualia.com/ - * - * - shows frustum, line of sight and up of the camera - * - suitable for fast updates - * - based on frustum visualization in lightgl.js shadowmap example - * http://evanw.github.com/lightgl.js/tests/shadowmap.html - */ - -THREE.CameraHelper = function ( camera ) { - - var geometry = new THREE.Geometry(); - var material = new THREE.LineBasicMaterial( { color: 0xffffff, vertexColors: THREE.FaceColors } ); - - var pointMap = {}; - - // colors - - var hexFrustum = 0xffaa00; - var hexCone = 0xff0000; - var hexUp = 0x00aaff; - var hexTarget = 0xffffff; - var hexCross = 0x333333; - - // near - - addLine( "n1", "n2", hexFrustum ); - addLine( "n2", "n4", hexFrustum ); - addLine( "n4", "n3", hexFrustum ); - addLine( "n3", "n1", hexFrustum ); - - // far - - addLine( "f1", "f2", hexFrustum ); - addLine( "f2", "f4", hexFrustum ); - addLine( "f4", "f3", hexFrustum ); - addLine( "f3", "f1", hexFrustum ); - - // sides - - addLine( "n1", "f1", hexFrustum ); - addLine( "n2", "f2", hexFrustum ); - addLine( "n3", "f3", hexFrustum ); - addLine( "n4", "f4", hexFrustum ); - - // cone - - addLine( "p", "n1", hexCone ); - addLine( "p", "n2", hexCone ); - addLine( "p", "n3", hexCone ); - addLine( "p", "n4", hexCone ); - - // up - - addLine( "u1", "u2", hexUp ); - addLine( "u2", "u3", hexUp ); - addLine( "u3", "u1", hexUp ); - - // target - - addLine( "c", "t", hexTarget ); - addLine( "p", "c", hexCross ); - - // cross - - addLine( "cn1", "cn2", hexCross ); - addLine( "cn3", "cn4", hexCross ); - - addLine( "cf1", "cf2", hexCross ); - addLine( "cf3", "cf4", hexCross ); - - function addLine( a, b, hex ) { - - addPoint( a, hex ); - addPoint( b, hex ); - - } - - function addPoint( id, hex ) { - - geometry.vertices.push( new THREE.Vector3() ); - geometry.colors.push( new THREE.Color( hex ) ); - - if ( pointMap[ id ] === undefined ) { - - pointMap[ id ] = []; - - } - - pointMap[ id ].push( geometry.vertices.length - 1 ); - - } - - THREE.Line.call( this, geometry, material, THREE.LinePieces ); - - this.camera = camera; - this.matrixWorld = camera.matrixWorld; - this.matrixAutoUpdate = false; - - this.pointMap = pointMap; - - this.update(); - -}; - -THREE.CameraHelper.prototype = Object.create( THREE.Line.prototype ); - -THREE.CameraHelper.prototype.update = function () { - - var vector = new THREE.Vector3(); - var camera = new THREE.Camera(); - var projector = new THREE.Projector(); - - return function () { - - var scope = this; - - var w = 1, h = 1; - - // we need just camera projection matrix - // world matrix must be identity - - camera.projectionMatrix.copy( this.camera.projectionMatrix ); - - // center / target - - setPoint( "c", 0, 0, -1 ); - setPoint( "t", 0, 0, 1 ); - - // near - - setPoint( "n1", -w, -h, -1 ); - setPoint( "n2", w, -h, -1 ); - setPoint( "n3", -w, h, -1 ); - setPoint( "n4", w, h, -1 ); - - // far - - setPoint( "f1", -w, -h, 1 ); - setPoint( "f2", w, -h, 1 ); - setPoint( "f3", -w, h, 1 ); - setPoint( "f4", w, h, 1 ); - - // up - - setPoint( "u1", w * 0.7, h * 1.1, -1 ); - setPoint( "u2", -w * 0.7, h * 1.1, -1 ); - setPoint( "u3", 0, h * 2, -1 ); - - // cross - - setPoint( "cf1", -w, 0, 1 ); - setPoint( "cf2", w, 0, 1 ); - setPoint( "cf3", 0, -h, 1 ); - setPoint( "cf4", 0, h, 1 ); - - setPoint( "cn1", -w, 0, -1 ); - setPoint( "cn2", w, 0, -1 ); - setPoint( "cn3", 0, -h, -1 ); - setPoint( "cn4", 0, h, -1 ); - - function setPoint( point, x, y, z ) { - - vector.set( x, y, z ); - projector.unprojectVector( vector, camera ); - - var points = scope.pointMap[ point ]; - - if ( points !== undefined ) { - - for ( var i = 0, il = points.length; i < il; i ++ ) { - - scope.geometry.vertices[ points[ i ] ].copy( vector ); - - } - - } - - } - - this.geometry.verticesNeedUpdate = true; - - }; - -}(); - -/** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - */ - -THREE.DirectionalLightHelper = function ( light, size ) { - - THREE.Object3D.call( this ); - - this.light = light; - this.light.updateMatrixWorld(); - - this.matrixWorld = light.matrixWorld; - this.matrixAutoUpdate = false; - - size = size || 1; - - var geometry = new THREE.Geometry(); - geometry.vertices.push( - new THREE.Vector3( - size, size, 0 ), - new THREE.Vector3( size, size, 0 ), - new THREE.Vector3( size, - size, 0 ), - new THREE.Vector3( - size, - size, 0 ), - new THREE.Vector3( - size, size, 0 ) - ); - - var material = new THREE.LineBasicMaterial( { fog: false } ); - material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); - - this.lightPlane = new THREE.Line( geometry, material ); - this.add( this.lightPlane ); - - geometry = new THREE.Geometry(); - geometry.vertices.push( - new THREE.Vector3(), - new THREE.Vector3() - ); - - material = new THREE.LineBasicMaterial( { fog: false } ); - material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); - - this.targetLine = new THREE.Line( geometry, material ); - this.add( this.targetLine ); - - this.update(); - -}; - -THREE.DirectionalLightHelper.prototype = Object.create( THREE.Object3D.prototype ); - -THREE.DirectionalLightHelper.prototype.dispose = function () { - - this.lightPlane.geometry.dispose(); - this.lightPlane.material.dispose(); - this.targetLine.geometry.dispose(); - this.targetLine.material.dispose(); -}; - -THREE.DirectionalLightHelper.prototype.update = function () { - - var v1 = new THREE.Vector3(); - var v2 = new THREE.Vector3(); - var v3 = new THREE.Vector3(); - - return function () { - - v1.setFromMatrixPosition( this.light.matrixWorld ); - v2.setFromMatrixPosition( this.light.target.matrixWorld ); - v3.subVectors( v2, v1 ); - - this.lightPlane.lookAt( v3 ); - this.lightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); - - this.targetLine.geometry.vertices[ 1 ].copy( v3 ); - this.targetLine.geometry.verticesNeedUpdate = true; - this.targetLine.material.color.copy( this.lightPlane.material.color ); - - } - -}(); - - -/** - * @author WestLangley / http://github.com/WestLangley - */ - -THREE.EdgesHelper = function ( object, hex ) { - - var color = ( hex !== undefined ) ? hex : 0xffffff; - - var edge = [ 0, 0 ], hash = {}; - var sortFunction = function ( a, b ) { return a - b }; - - var keys = [ 'a', 'b', 'c' ]; - var geometry = new THREE.BufferGeometry(); - - var geometry2 = object.geometry.clone(); - - geometry2.mergeVertices(); - geometry2.computeFaceNormals(); - - var vertices = geometry2.vertices; - var faces = geometry2.faces; - var numEdges = 0; - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - var face = faces[ i ]; - - for ( var j = 0; j < 3; j ++ ) { - - edge[ 0 ] = face[ keys[ j ] ]; - edge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ]; - edge.sort( sortFunction ); - - var key = edge.toString(); - - if ( hash[ key ] === undefined ) { - - hash[ key ] = { vert1: edge[ 0 ], vert2: edge[ 1 ], face1: i, face2: undefined }; - numEdges ++; - - } else { - - hash[ key ].face2 = i; - - } - - } - - } - - geometry.addAttribute( 'position', new THREE.Float32Attribute( numEdges * 2, 3 ) ); - - var coords = geometry.attributes.position.array; - - var index = 0; - - for ( var key in hash ) { - - var h = hash[ key ]; - - if ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) < 0.9999 ) { // hardwired const OK - - var vertex = vertices[ h.vert1 ]; - coords[ index ++ ] = vertex.x; - coords[ index ++ ] = vertex.y; - coords[ index ++ ] = vertex.z; - - vertex = vertices[ h.vert2 ]; - coords[ index ++ ] = vertex.x; - coords[ index ++ ] = vertex.y; - coords[ index ++ ] = vertex.z; - - } - - } - - THREE.Line.call( this, geometry, new THREE.LineBasicMaterial( { color: color } ), THREE.LinePieces ); - - this.matrixAutoUpdate = false; - this.matrixWorld = object.matrixWorld; - -}; - -THREE.EdgesHelper.prototype = Object.create( THREE.Line.prototype ); - -/** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley -*/ - -THREE.FaceNormalsHelper = function ( object, size, hex, linewidth ) { - - this.object = object; - - this.size = ( size !== undefined ) ? size : 1; - - var color = ( hex !== undefined ) ? hex : 0xffff00; - - var width = ( linewidth !== undefined ) ? linewidth : 1; - - var geometry = new THREE.Geometry(); - - var faces = this.object.geometry.faces; - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - geometry.vertices.push( new THREE.Vector3(), new THREE.Vector3() ); - - } - - THREE.Line.call( this, geometry, new THREE.LineBasicMaterial( { color: color, linewidth: width } ), THREE.LinePieces ); - - this.matrixAutoUpdate = false; - - this.normalMatrix = new THREE.Matrix3(); - - this.update(); - -}; - -THREE.FaceNormalsHelper.prototype = Object.create( THREE.Line.prototype ); - -THREE.FaceNormalsHelper.prototype.update = function () { - - var vertices = this.geometry.vertices; - - var object = this.object; - var objectVertices = object.geometry.vertices; - var objectFaces = object.geometry.faces; - var objectWorldMatrix = object.matrixWorld; - - object.updateMatrixWorld( true ); - - this.normalMatrix.getNormalMatrix( objectWorldMatrix ); - - for ( var i = 0, i2 = 0, l = objectFaces.length; i < l; i ++, i2 += 2 ) { - - var face = objectFaces[ i ]; - - vertices[ i2 ].copy( objectVertices[ face.a ] ) - .add( objectVertices[ face.b ] ) - .add( objectVertices[ face.c ] ) - .divideScalar( 3 ) - .applyMatrix4( objectWorldMatrix ); - - vertices[ i2 + 1 ].copy( face.normal ) - .applyMatrix3( this.normalMatrix ) - .normalize() - .multiplyScalar( this.size ) - .add( vertices[ i2 ] ); - - } - - this.geometry.verticesNeedUpdate = true; - - return this; - -}; - - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.GridHelper = function ( size, step ) { - - var geometry = new THREE.Geometry(); - var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } ); - - this.color1 = new THREE.Color( 0x444444 ); - this.color2 = new THREE.Color( 0x888888 ); - - for ( var i = - size; i <= size; i += step ) { - - geometry.vertices.push( - new THREE.Vector3( - size, 0, i ), new THREE.Vector3( size, 0, i ), - new THREE.Vector3( i, 0, - size ), new THREE.Vector3( i, 0, size ) - ); - - var color = i === 0 ? this.color1 : this.color2; - - geometry.colors.push( color, color, color, color ); - - } - - THREE.Line.call( this, geometry, material, THREE.LinePieces ); - -}; - -THREE.GridHelper.prototype = Object.create( THREE.Line.prototype ); - -THREE.GridHelper.prototype.setColors = function( colorCenterLine, colorGrid ) { - - this.color1.set( colorCenterLine ); - this.color2.set( colorGrid ); - - this.geometry.colorsNeedUpdate = true; - -} - -/** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.HemisphereLightHelper = function ( light, sphereSize, arrowLength, domeSize ) { - - THREE.Object3D.call( this ); - - this.light = light; - this.light.updateMatrixWorld(); - - this.matrixWorld = light.matrixWorld; - this.matrixAutoUpdate = false; - - this.colors = [ new THREE.Color(), new THREE.Color() ]; - - var geometry = new THREE.SphereGeometry( sphereSize, 4, 2 ); - geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) ); - - for ( var i = 0, il = 8; i < il; i ++ ) { - - geometry.faces[ i ].color = this.colors[ i < 4 ? 0 : 1 ]; - - } - - var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, wireframe: true } ); - - this.lightSphere = new THREE.Mesh( geometry, material ); - this.add( this.lightSphere ); - - this.update(); - -}; - -THREE.HemisphereLightHelper.prototype = Object.create( THREE.Object3D.prototype ); - -THREE.HemisphereLightHelper.prototype.dispose = function () { - this.lightSphere.geometry.dispose(); - this.lightSphere.material.dispose(); -}; - -THREE.HemisphereLightHelper.prototype.update = function () { - - var vector = new THREE.Vector3(); - - return function () { - - this.colors[ 0 ].copy( this.light.color ).multiplyScalar( this.light.intensity ); - this.colors[ 1 ].copy( this.light.groundColor ).multiplyScalar( this.light.intensity ); - - this.lightSphere.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() ); - this.lightSphere.geometry.colorsNeedUpdate = true; - - } - -}(); - - -/** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.PointLightHelper = function ( light, sphereSize ) { - - this.light = light; - this.light.updateMatrixWorld(); - - var geometry = new THREE.SphereGeometry( sphereSize, 4, 2 ); - var material = new THREE.MeshBasicMaterial( { wireframe: true, fog: false } ); - material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); - - THREE.Mesh.call( this, geometry, material ); - - this.matrixWorld = this.light.matrixWorld; - this.matrixAutoUpdate = false; - - /* - var distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 ); - var distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } ); - - this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial ); - this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial ); - - var d = light.distance; - - if ( d === 0.0 ) { - - this.lightDistance.visible = false; - - } else { - - this.lightDistance.scale.set( d, d, d ); - - } - - this.add( this.lightDistance ); - */ - -}; - -THREE.PointLightHelper.prototype = Object.create( THREE.Mesh.prototype ); - -THREE.PointLightHelper.prototype.dispose = function () { - - this.geometry.dispose(); - this.material.dispose(); -}; - -THREE.PointLightHelper.prototype.update = function () { - - this.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); - - /* - var d = this.light.distance; - - if ( d === 0.0 ) { - - this.lightDistance.visible = false; - - } else { - - this.lightDistance.visible = true; - this.lightDistance.scale.set( d, d, d ); - - } - */ - -}; - - -/** - * @author Sean Griffin / http://twitter.com/sgrif - * @author Michael Guerrero / http://realitymeltdown.com - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.SkeletonHelper = function ( object ) { - - var skeleton = object.skeleton; - - var geometry = new THREE.Geometry(); - - for ( var i = 0; i < skeleton.bones.length; i ++ ) { - - var bone = skeleton.bones[ i ]; - - if ( bone.parent instanceof THREE.Bone ) { - - geometry.vertices.push( new THREE.Vector3() ); - geometry.vertices.push( new THREE.Vector3() ); - geometry.colors.push( new THREE.Color( 0, 0, 1 ) ); - geometry.colors.push( new THREE.Color( 0, 1, 0 ) ); - - } - - } - - var material = new THREE.LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, transparent: true } ); - - THREE.Line.call( this, geometry, material, THREE.LinePieces ); - - this.skeleton = skeleton; - - this.matrixWorld = object.matrixWorld; - this.matrixAutoUpdate = false; - - this.update(); - -}; - - -THREE.SkeletonHelper.prototype = Object.create( THREE.Line.prototype ); - -THREE.SkeletonHelper.prototype.update = function () { - - var geometry = this.geometry; - - var j = 0; - - for ( var i = 0; i < this.skeleton.bones.length; i ++ ) { - - var bone = this.skeleton.bones[ i ]; - - if ( bone.parent instanceof THREE.Bone ) { - - geometry.vertices[ j ].setFromMatrixPosition( bone.skinMatrix ); - geometry.vertices[ j + 1 ].setFromMatrixPosition( bone.parent.skinMatrix ); - - j += 2; - - } - - } - - geometry.verticesNeedUpdate = true; - - geometry.computeBoundingSphere(); - -}; - -/** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley -*/ - -THREE.SpotLightHelper = function ( light ) { - - THREE.Object3D.call( this ); - - this.light = light; - this.light.updateMatrixWorld(); - - this.matrixWorld = light.matrixWorld; - this.matrixAutoUpdate = false; - - var geometry = new THREE.CylinderGeometry( 0, 1, 1, 8, 1, true ); - - geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, -0.5, 0 ) ); - geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) ); - - var material = new THREE.MeshBasicMaterial( { wireframe: true, fog: false } ); - - this.cone = new THREE.Mesh( geometry, material ); - this.add( this.cone ); - - this.update(); - -}; - -THREE.SpotLightHelper.prototype = Object.create( THREE.Object3D.prototype ); - -THREE.SpotLightHelper.prototype.dispose = function () { - this.cone.geometry.dispose(); - this.cone.material.dispose(); -}; - -THREE.SpotLightHelper.prototype.update = function () { - - var vector = new THREE.Vector3(); - var vector2 = new THREE.Vector3(); - - return function () { - - var coneLength = this.light.distance ? this.light.distance : 10000; - var coneWidth = coneLength * Math.tan( this.light.angle ); - - this.cone.scale.set( coneWidth, coneWidth, coneLength ); - - vector.setFromMatrixPosition( this.light.matrixWorld ); - vector2.setFromMatrixPosition( this.light.target.matrixWorld ); - - this.cone.lookAt( vector2.sub( vector ) ); - - this.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); - - }; - -}(); - -/** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley -*/ - -THREE.VertexNormalsHelper = function ( object, size, hex, linewidth ) { - - this.object = object; - - this.size = ( size !== undefined ) ? size : 1; - - var color = ( hex !== undefined ) ? hex : 0xff0000; - - var width = ( linewidth !== undefined ) ? linewidth : 1; - - var geometry = new THREE.Geometry(); - - var vertices = object.geometry.vertices; - - var faces = object.geometry.faces; - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - var face = faces[ i ]; - - for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { - - geometry.vertices.push( new THREE.Vector3() ); - geometry.vertices.push( new THREE.Vector3() ); - - } - - } - - THREE.Line.call( this, geometry, new THREE.LineBasicMaterial( { color: color, linewidth: width } ), THREE.LinePieces ); - - this.matrixAutoUpdate = false; - - this.normalMatrix = new THREE.Matrix3(); - - this.update(); - -}; - -THREE.VertexNormalsHelper.prototype = Object.create( THREE.Line.prototype ); - -THREE.VertexNormalsHelper.prototype.update = ( function ( object ) { - - var v1 = new THREE.Vector3(); - - return function( object ) { - - var keys = [ 'a', 'b', 'c', 'd' ]; - - this.object.updateMatrixWorld( true ); - - this.normalMatrix.getNormalMatrix( this.object.matrixWorld ); - - var vertices = this.geometry.vertices; - - var verts = this.object.geometry.vertices; - - var faces = this.object.geometry.faces; - - var worldMatrix = this.object.matrixWorld; - - var idx = 0; - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - var face = faces[ i ]; - - for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { - - var vertexId = face[ keys[ j ] ]; - var vertex = verts[ vertexId ]; - - var normal = face.vertexNormals[ j ]; - - vertices[ idx ].copy( vertex ).applyMatrix4( worldMatrix ); - - v1.copy( normal ).applyMatrix3( this.normalMatrix ).normalize().multiplyScalar( this.size ); - - v1.add( vertices[ idx ] ); - idx = idx + 1; - - vertices[ idx ].copy( v1 ); - idx = idx + 1; - - } - - } - - this.geometry.verticesNeedUpdate = true; - - return this; - - } - -}()); - -/** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley -*/ - -THREE.VertexTangentsHelper = function ( object, size, hex, linewidth ) { - - this.object = object; - - this.size = ( size !== undefined ) ? size : 1; - - var color = ( hex !== undefined ) ? hex : 0x0000ff; - - var width = ( linewidth !== undefined ) ? linewidth : 1; - - var geometry = new THREE.Geometry(); - - var vertices = object.geometry.vertices; - - var faces = object.geometry.faces; - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - var face = faces[ i ]; - - for ( var j = 0, jl = face.vertexTangents.length; j < jl; j ++ ) { - - geometry.vertices.push( new THREE.Vector3() ); - geometry.vertices.push( new THREE.Vector3() ); - - } - - } - - THREE.Line.call( this, geometry, new THREE.LineBasicMaterial( { color: color, linewidth: width } ), THREE.LinePieces ); - - this.matrixAutoUpdate = false; - - this.update(); - -}; - -THREE.VertexTangentsHelper.prototype = Object.create( THREE.Line.prototype ); - -THREE.VertexTangentsHelper.prototype.update = ( function ( object ) { - - var v1 = new THREE.Vector3(); - - return function( object ) { - - var keys = [ 'a', 'b', 'c', 'd' ]; - - this.object.updateMatrixWorld( true ); - - var vertices = this.geometry.vertices; - - var verts = this.object.geometry.vertices; - - var faces = this.object.geometry.faces; - - var worldMatrix = this.object.matrixWorld; - - var idx = 0; - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - var face = faces[ i ]; - - for ( var j = 0, jl = face.vertexTangents.length; j < jl; j ++ ) { - - var vertexId = face[ keys[ j ] ]; - var vertex = verts[ vertexId ]; - - var tangent = face.vertexTangents[ j ]; - - vertices[ idx ].copy( vertex ).applyMatrix4( worldMatrix ); - - v1.copy( tangent ).transformDirection( worldMatrix ).multiplyScalar( this.size ); - - v1.add( vertices[ idx ] ); - idx = idx + 1; - - vertices[ idx ].copy( v1 ); - idx = idx + 1; - - } - - } - - this.geometry.verticesNeedUpdate = true; - - return this; - - } - -}()); - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -THREE.WireframeHelper = function ( object, hex ) { - - var color = ( hex !== undefined ) ? hex : 0xffffff; - - var edge = [ 0, 0 ], hash = {}; - var sortFunction = function ( a, b ) { return a - b }; - - var keys = [ 'a', 'b', 'c' ]; - var geometry = new THREE.BufferGeometry(); - - if ( object.geometry instanceof THREE.Geometry ) { - - var vertices = object.geometry.vertices; - var faces = object.geometry.faces; - var numEdges = 0; - - // allocate maximal size - var edges = new Uint32Array( 6 * faces.length ); - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - var face = faces[ i ]; - - for ( var j = 0; j < 3; j ++ ) { - - edge[ 0 ] = face[ keys[ j ] ]; - edge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ]; - edge.sort( sortFunction ); - - var key = edge.toString(); - - if ( hash[ key ] === undefined ) { - - edges[ 2 * numEdges ] = edge[ 0 ]; - edges[ 2 * numEdges + 1 ] = edge[ 1 ]; - hash[ key ] = true; - numEdges ++; - - } - - } - - } - - geometry.addAttribute( 'position', new THREE.Float32Attribute( numEdges * 2, 3 ) ); - - var coords = geometry.attributes.position.array; - - for ( var i = 0, l = numEdges; i < l; i ++ ) { - - for ( var j = 0; j < 2; j ++ ) { - - var vertex = vertices[ edges [ 2 * i + j] ]; - - var index = 6 * i + 3 * j; - coords[ index + 0 ] = vertex.x; - coords[ index + 1 ] = vertex.y; - coords[ index + 2 ] = vertex.z; - - } - - } - - } else if ( object.geometry instanceof THREE.BufferGeometry && object.geometry.attributes.index !== undefined ) { // indexed BufferGeometry - - var vertices = object.geometry.attributes.position.array; - var indices = object.geometry.attributes.index.array; - var offsets = object.geometry.offsets; - var numEdges = 0; - - // allocate maximal size - var edges = new Uint32Array( 2 * indices.length ); - - for ( var o = 0, ol = offsets.length; o < ol; ++ o ) { - - var start = offsets[ o ].start; - var count = offsets[ o ].count; - var index = offsets[ o ].index; - - for ( var i = start, il = start + count; i < il; i += 3 ) { - - for ( var j = 0; j < 3; j ++ ) { - - edge[ 0 ] = index + indices[ i + j ]; - edge[ 1 ] = index + indices[ i + ( j + 1 ) % 3 ]; - edge.sort( sortFunction ); - - var key = edge.toString(); - - if ( hash[ key ] === undefined ) { - - edges[ 2 * numEdges ] = edge[ 0 ]; - edges[ 2 * numEdges + 1 ] = edge[ 1 ]; - hash[ key ] = true; - numEdges ++; - - } - - } - - } - - } - - geometry.addAttribute( 'position', new THREE.Float32Attribute( numEdges * 2, 3 ) ); - - var coords = geometry.attributes.position.array; - - for ( var i = 0, l = numEdges; i < l; i ++ ) { - - for ( var j = 0; j < 2; j ++ ) { - - var index = 6 * i + 3 * j; - var index2 = 3 * edges[ 2 * i + j]; - coords[ index + 0 ] = vertices[ index2 ]; - coords[ index + 1 ] = vertices[ index2 + 1 ]; - coords[ index + 2 ] = vertices[ index2 + 2 ]; - - } - - } - - } else if ( object.geometry instanceof THREE.BufferGeometry ) { // non-indexed BufferGeometry - - var vertices = object.geometry.attributes.position.array; - var numEdges = vertices.length / 3; - var numTris = numEdges / 3; - - geometry.addAttribute( 'position', new THREE.Float32Attribute( numEdges * 2, 3 ) ); - - var coords = geometry.attributes.position.array; - - for ( var i = 0, l = numTris; i < l; i ++ ) { - - for ( var j = 0; j < 3; j ++ ) { - - var index = 18 * i + 6 * j; - - var index1 = 9 * i + 3 * j; - coords[ index + 0 ] = vertices[ index1 ]; - coords[ index + 1 ] = vertices[ index1 + 1 ]; - coords[ index + 2 ] = vertices[ index1 + 2 ]; - - var index2 = 9 * i + 3 * ( ( j + 1 ) % 3 ); - coords[ index + 3 ] = vertices[ index2 ]; - coords[ index + 4 ] = vertices[ index2 + 1 ]; - coords[ index + 5 ] = vertices[ index2 + 2 ]; - - } - - } - - } - - THREE.Line.call( this, geometry, new THREE.LineBasicMaterial( { color: color } ), THREE.LinePieces ); - - this.matrixAutoUpdate = false; - this.matrixWorld = object.matrixWorld; - -}; - -THREE.WireframeHelper.prototype = Object.create( THREE.Line.prototype ); - -/** - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.ImmediateRenderObject = function () { - - THREE.Object3D.call( this ); - - this.render = function ( renderCallback ) { }; - -}; - -THREE.ImmediateRenderObject.prototype = Object.create( THREE.Object3D.prototype ); - -/** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.LensFlare = function ( texture, size, distance, blending, color ) { - - THREE.Object3D.call( this ); - - this.lensFlares = []; - - this.positionScreen = new THREE.Vector3(); - this.customUpdateCallback = undefined; - - if( texture !== undefined ) { - - this.add( texture, size, distance, blending, color ); - - } - -}; - -THREE.LensFlare.prototype = Object.create( THREE.Object3D.prototype ); - - -/* - * Add: adds another flare - */ - -THREE.LensFlare.prototype.add = function ( texture, size, distance, blending, color, opacity ) { - - if( size === undefined ) size = -1; - if( distance === undefined ) distance = 0; - if( opacity === undefined ) opacity = 1; - if( color === undefined ) color = new THREE.Color( 0xffffff ); - if( blending === undefined ) blending = THREE.NormalBlending; - - distance = Math.min( distance, Math.max( 0, distance ) ); - - this.lensFlares.push( { texture: texture, // THREE.Texture - size: size, // size in pixels (-1 = use texture.width) - distance: distance, // distance (0-1) from light source (0=at light source) - x: 0, y: 0, z: 0, // screen position (-1 => 1) z = 0 is ontop z = 1 is back - scale: 1, // scale - rotation: 1, // rotation - opacity: opacity, // opacity - color: color, // color - blending: blending } ); // blending - -}; - - -/* - * Update lens flares update positions on all flares based on the screen position - * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way. - */ - -THREE.LensFlare.prototype.updateLensFlares = function () { - - var f, fl = this.lensFlares.length; - var flare; - var vecX = -this.positionScreen.x * 2; - var vecY = -this.positionScreen.y * 2; - - for( f = 0; f < fl; f ++ ) { - - flare = this.lensFlares[ f ]; - - flare.x = this.positionScreen.x + vecX * flare.distance; - flare.y = this.positionScreen.y + vecY * flare.distance; - - flare.wantedRotation = flare.x * Math.PI * 0.25; - flare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25; - - } - -}; - - - - - - - - - - - - - -/** - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.MorphBlendMesh = function( geometry, material ) { - - THREE.Mesh.call( this, geometry, material ); - - this.animationsMap = {}; - this.animationsList = []; - - // prepare default animation - // (all frames played together in 1 second) - - var numFrames = this.geometry.morphTargets.length; - - var name = "__default"; - - var startFrame = 0; - var endFrame = numFrames - 1; - - var fps = numFrames / 1; - - this.createAnimation( name, startFrame, endFrame, fps ); - this.setAnimationWeight( name, 1 ); - -}; - -THREE.MorphBlendMesh.prototype = Object.create( THREE.Mesh.prototype ); - -THREE.MorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) { - - var animation = { - - startFrame: start, - endFrame: end, - - length: end - start + 1, - - fps: fps, - duration: ( end - start ) / fps, - - lastFrame: 0, - currentFrame: 0, - - active: false, - - time: 0, - direction: 1, - weight: 1, - - directionBackwards: false, - mirroredLoop: false - - }; - - this.animationsMap[ name ] = animation; - this.animationsList.push( animation ); - -}; - -THREE.MorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) { - - var pattern = /([a-z]+)(\d+)/; - - var firstAnimation, frameRanges = {}; - - var geometry = this.geometry; - - for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) { - - var morph = geometry.morphTargets[ i ]; - var chunks = morph.name.match( pattern ); - - if ( chunks && chunks.length > 1 ) { - - var name = chunks[ 1 ]; - var num = chunks[ 2 ]; - - if ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: -Infinity }; - - var range = frameRanges[ name ]; - - if ( i < range.start ) range.start = i; - if ( i > range.end ) range.end = i; - - if ( ! firstAnimation ) firstAnimation = name; - - } - - } - - for ( var name in frameRanges ) { - - var range = frameRanges[ name ]; - this.createAnimation( name, range.start, range.end, fps ); - - } - - this.firstAnimation = firstAnimation; - -}; - -THREE.MorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) { - - var animation = this.animationsMap[ name ]; - - if ( animation ) { - - animation.direction = 1; - animation.directionBackwards = false; - - } - -}; - -THREE.MorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) { - - var animation = this.animationsMap[ name ]; - - if ( animation ) { - - animation.direction = -1; - animation.directionBackwards = true; - - } - -}; - -THREE.MorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) { - - var animation = this.animationsMap[ name ]; - - if ( animation ) { - - animation.fps = fps; - animation.duration = ( animation.end - animation.start ) / animation.fps; - - } - -}; - -THREE.MorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) { - - var animation = this.animationsMap[ name ]; - - if ( animation ) { - - animation.duration = duration; - animation.fps = ( animation.end - animation.start ) / animation.duration; - - } - -}; - -THREE.MorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) { - - var animation = this.animationsMap[ name ]; - - if ( animation ) { - - animation.weight = weight; - - } - -}; - -THREE.MorphBlendMesh.prototype.setAnimationTime = function ( name, time ) { - - var animation = this.animationsMap[ name ]; - - if ( animation ) { - - animation.time = time; - - } - -}; - -THREE.MorphBlendMesh.prototype.getAnimationTime = function ( name ) { - - var time = 0; - - var animation = this.animationsMap[ name ]; - - if ( animation ) { - - time = animation.time; - - } - - return time; - -}; - -THREE.MorphBlendMesh.prototype.getAnimationDuration = function ( name ) { - - var duration = -1; - - var animation = this.animationsMap[ name ]; - - if ( animation ) { - - duration = animation.duration; - - } - - return duration; - -}; - -THREE.MorphBlendMesh.prototype.playAnimation = function ( name ) { - - var animation = this.animationsMap[ name ]; - - if ( animation ) { - - animation.time = 0; - animation.active = true; - - } else { - - console.warn( "animation[" + name + "] undefined" ); - - } - -}; - -THREE.MorphBlendMesh.prototype.stopAnimation = function ( name ) { - - var animation = this.animationsMap[ name ]; - - if ( animation ) { - - animation.active = false; - - } - -}; - -THREE.MorphBlendMesh.prototype.update = function ( delta ) { - - for ( var i = 0, il = this.animationsList.length; i < il; i ++ ) { - - var animation = this.animationsList[ i ]; - - if ( ! animation.active ) continue; - - var frameTime = animation.duration / animation.length; - - animation.time += animation.direction * delta; - - if ( animation.mirroredLoop ) { - - if ( animation.time > animation.duration || animation.time < 0 ) { - - animation.direction *= -1; - - if ( animation.time > animation.duration ) { - - animation.time = animation.duration; - animation.directionBackwards = true; - - } - - if ( animation.time < 0 ) { - - animation.time = 0; - animation.directionBackwards = false; - - } - - } - - } else { - - animation.time = animation.time % animation.duration; - - if ( animation.time < 0 ) animation.time += animation.duration; - - } - - var keyframe = animation.startFrame + THREE.Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 ); - var weight = animation.weight; - - if ( keyframe !== animation.currentFrame ) { - - this.morphTargetInfluences[ animation.lastFrame ] = 0; - this.morphTargetInfluences[ animation.currentFrame ] = 1 * weight; - - this.morphTargetInfluences[ keyframe ] = 0; - - animation.lastFrame = animation.currentFrame; - animation.currentFrame = keyframe; - - } - - var mix = ( animation.time % frameTime ) / frameTime; - - if ( animation.directionBackwards ) mix = 1 - mix; - - this.morphTargetInfluences[ animation.currentFrame ] = mix * weight; - this.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight; - - } - -}; - -/** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.LensFlarePlugin = function () { - - var _gl, _renderer, _precision, _lensFlare = {}; - - this.init = function ( renderer ) { - - _gl = renderer.context; - _renderer = renderer; - - _precision = renderer.getPrecision(); - - _lensFlare.vertices = new Float32Array( 8 + 8 ); - _lensFlare.faces = new Uint16Array( 6 ); - - var i = 0; - _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = -1; // vertex - _lensFlare.vertices[ i++ ] = 0; _lensFlare.vertices[ i++ ] = 0; // uv... etc. - - _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = -1; - _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 0; - - _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 1; - _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 1; - - _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = 1; - _lensFlare.vertices[ i++ ] = 0; _lensFlare.vertices[ i++ ] = 1; - - i = 0; - _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 1; _lensFlare.faces[ i++ ] = 2; - _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 2; _lensFlare.faces[ i++ ] = 3; - - // buffers - - _lensFlare.vertexBuffer = _gl.createBuffer(); - _lensFlare.elementBuffer = _gl.createBuffer(); - - _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, _lensFlare.vertices, _gl.STATIC_DRAW ); - - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer ); - _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.faces, _gl.STATIC_DRAW ); - - // textures - - _lensFlare.tempTexture = _gl.createTexture(); - _lensFlare.occlusionTexture = _gl.createTexture(); - - _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture ); - _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, 16, 16, 0, _gl.RGB, _gl.UNSIGNED_BYTE, null ); - _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE ); - _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE ); - _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST ); - _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST ); - - _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture ); - _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, 16, 16, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, null ); - _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE ); - _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE ); - _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST ); - _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST ); - - if ( _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) <= 0 ) { - - _lensFlare.hasVertexTexture = false; - _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlare" ], _precision ); - - } else { - - _lensFlare.hasVertexTexture = true; - _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlareVertexTexture" ], _precision ); - - } - - _lensFlare.attributes = {}; - _lensFlare.uniforms = {}; - - _lensFlare.attributes.vertex = _gl.getAttribLocation ( _lensFlare.program, "position" ); - _lensFlare.attributes.uv = _gl.getAttribLocation ( _lensFlare.program, "uv" ); - - _lensFlare.uniforms.renderType = _gl.getUniformLocation( _lensFlare.program, "renderType" ); - _lensFlare.uniforms.map = _gl.getUniformLocation( _lensFlare.program, "map" ); - _lensFlare.uniforms.occlusionMap = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" ); - _lensFlare.uniforms.opacity = _gl.getUniformLocation( _lensFlare.program, "opacity" ); - _lensFlare.uniforms.color = _gl.getUniformLocation( _lensFlare.program, "color" ); - _lensFlare.uniforms.scale = _gl.getUniformLocation( _lensFlare.program, "scale" ); - _lensFlare.uniforms.rotation = _gl.getUniformLocation( _lensFlare.program, "rotation" ); - _lensFlare.uniforms.screenPosition = _gl.getUniformLocation( _lensFlare.program, "screenPosition" ); - - }; - - - /* - * Render lens flares - * Method: renders 16x16 0xff00ff-colored points scattered over the light source area, - * reads these back and calculates occlusion. - * Then _lensFlare.update_lensFlares() is called to re-position and - * update transparency of flares. Then they are rendered. - * - */ - - this.render = function ( scene, camera, viewportWidth, viewportHeight ) { - - var flares = scene.__webglFlares, - nFlares = flares.length; - - if ( ! nFlares ) return; - - var tempPosition = new THREE.Vector3(); - - var invAspect = viewportHeight / viewportWidth, - halfViewportWidth = viewportWidth * 0.5, - halfViewportHeight = viewportHeight * 0.5; - - var size = 16 / viewportHeight, - scale = new THREE.Vector2( size * invAspect, size ); - - var screenPosition = new THREE.Vector3( 1, 1, 0 ), - screenPositionPixels = new THREE.Vector2( 1, 1 ); - - var uniforms = _lensFlare.uniforms, - attributes = _lensFlare.attributes; - - // set _lensFlare program and reset blending - - _gl.useProgram( _lensFlare.program ); - - _gl.enableVertexAttribArray( _lensFlare.attributes.vertex ); - _gl.enableVertexAttribArray( _lensFlare.attributes.uv ); - - // loop through all lens flares to update their occlusion and positions - // setup gl and common used attribs/unforms - - _gl.uniform1i( uniforms.occlusionMap, 0 ); - _gl.uniform1i( uniforms.map, 1 ); - - _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer ); - _gl.vertexAttribPointer( attributes.vertex, 2, _gl.FLOAT, false, 2 * 8, 0 ); - _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 ); - - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer ); - - _gl.disable( _gl.CULL_FACE ); - _gl.depthMask( false ); - - var i, j, jl, flare, sprite; - - for ( i = 0; i < nFlares; i ++ ) { - - size = 16 / viewportHeight; - scale.set( size * invAspect, size ); - - // calc object screen position - - flare = flares[ i ]; - - tempPosition.set( flare.matrixWorld.elements[12], flare.matrixWorld.elements[13], flare.matrixWorld.elements[14] ); - - tempPosition.applyMatrix4( camera.matrixWorldInverse ); - tempPosition.applyProjection( camera.projectionMatrix ); - - // setup arrays for gl programs - - screenPosition.copy( tempPosition ) - - screenPositionPixels.x = screenPosition.x * halfViewportWidth + halfViewportWidth; - screenPositionPixels.y = screenPosition.y * halfViewportHeight + halfViewportHeight; - - // screen cull - - if ( _lensFlare.hasVertexTexture || ( - screenPositionPixels.x > 0 && - screenPositionPixels.x < viewportWidth && - screenPositionPixels.y > 0 && - screenPositionPixels.y < viewportHeight ) ) { - - // save current RGB to temp texture - - _gl.activeTexture( _gl.TEXTURE1 ); - _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture ); - _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 ); - - - // render pink quad - - _gl.uniform1i( uniforms.renderType, 0 ); - _gl.uniform2f( uniforms.scale, scale.x, scale.y ); - _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z ); - - _gl.disable( _gl.BLEND ); - _gl.enable( _gl.DEPTH_TEST ); - - _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 ); - - - // copy result to occlusionMap - - _gl.activeTexture( _gl.TEXTURE0 ); - _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture ); - _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 ); - - - // restore graphics - - _gl.uniform1i( uniforms.renderType, 1 ); - _gl.disable( _gl.DEPTH_TEST ); - - _gl.activeTexture( _gl.TEXTURE1 ); - _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture ); - _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 ); - - - // update object positions - - flare.positionScreen.copy( screenPosition ) - - if ( flare.customUpdateCallback ) { - - flare.customUpdateCallback( flare ); - - } else { - - flare.updateLensFlares(); - - } - - // render flares - - _gl.uniform1i( uniforms.renderType, 2 ); - _gl.enable( _gl.BLEND ); - - for ( j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) { - - sprite = flare.lensFlares[ j ]; - - if ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) { - - screenPosition.x = sprite.x; - screenPosition.y = sprite.y; - screenPosition.z = sprite.z; - - size = sprite.size * sprite.scale / viewportHeight; - - scale.x = size * invAspect; - scale.y = size; - - _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z ); - _gl.uniform2f( uniforms.scale, scale.x, scale.y ); - _gl.uniform1f( uniforms.rotation, sprite.rotation ); - - _gl.uniform1f( uniforms.opacity, sprite.opacity ); - _gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b ); - - _renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst ); - _renderer.setTexture( sprite.texture, 1 ); - - _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 ); - - } - - } - - } - - } - - // restore gl - - _gl.enable( _gl.CULL_FACE ); - _gl.enable( _gl.DEPTH_TEST ); - _gl.depthMask( true ); - - }; - - function createProgram ( shader, precision ) { - - var program = _gl.createProgram(); - - var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER ); - var vertexShader = _gl.createShader( _gl.VERTEX_SHADER ); - - var prefix = "precision " + precision + " float;\n"; - - _gl.shaderSource( fragmentShader, prefix + shader.fragmentShader ); - _gl.shaderSource( vertexShader, prefix + shader.vertexShader ); - - _gl.compileShader( fragmentShader ); - _gl.compileShader( vertexShader ); - - _gl.attachShader( program, fragmentShader ); - _gl.attachShader( program, vertexShader ); - - _gl.linkProgram( program ); - - return program; - - }; - -}; - -/** - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.ShadowMapPlugin = function () { - - var _gl, - _renderer, - _depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin, - - _frustum = new THREE.Frustum(), - _projScreenMatrix = new THREE.Matrix4(), - - _min = new THREE.Vector3(), - _max = new THREE.Vector3(), - - _matrixPosition = new THREE.Vector3(); - - this.init = function ( renderer ) { - - _gl = renderer.context; - _renderer = renderer; - - var depthShader = THREE.ShaderLib[ "depthRGBA" ]; - var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms ); - - _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } ); - _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } ); - _depthMaterialSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, skinning: true } ); - _depthMaterialMorphSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true, skinning: true } ); - - _depthMaterial._shadowPass = true; - _depthMaterialMorph._shadowPass = true; - _depthMaterialSkin._shadowPass = true; - _depthMaterialMorphSkin._shadowPass = true; - - }; - - this.render = function ( scene, camera ) { - - if ( ! ( _renderer.shadowMapEnabled && _renderer.shadowMapAutoUpdate ) ) return; - - this.update( scene, camera ); - - }; - - this.update = function ( scene, camera ) { - - var i, il, j, jl, n, - - shadowMap, shadowMatrix, shadowCamera, - program, buffer, material, - webglObject, object, light, - renderList, - - lights = [], - k = 0, - - fog = null; - - // set GL state for depth map - - _gl.clearColor( 1, 1, 1, 1 ); - _gl.disable( _gl.BLEND ); - - _gl.enable( _gl.CULL_FACE ); - _gl.frontFace( _gl.CCW ); - - if ( _renderer.shadowMapCullFace === THREE.CullFaceFront ) { - - _gl.cullFace( _gl.FRONT ); - - } else { - - _gl.cullFace( _gl.BACK ); - - } - - _renderer.setDepthTest( true ); - - // preprocess lights - // - skip lights that are not casting shadows - // - create virtual lights for cascaded shadow maps - - for ( i = 0, il = scene.__lights.length; i < il; i ++ ) { - - light = scene.__lights[ i ]; - - if ( ! light.castShadow ) continue; - - if ( ( light instanceof THREE.DirectionalLight ) && light.shadowCascade ) { - - for ( n = 0; n < light.shadowCascadeCount; n ++ ) { - - var virtualLight; - - if ( ! light.shadowCascadeArray[ n ] ) { - - virtualLight = createVirtualLight( light, n ); - virtualLight.originalCamera = camera; - - var gyro = new THREE.Gyroscope(); - gyro.position.copy( light.shadowCascadeOffset ); - - gyro.add( virtualLight ); - gyro.add( virtualLight.target ); - - camera.add( gyro ); - - light.shadowCascadeArray[ n ] = virtualLight; - - console.log( "Created virtualLight", virtualLight ); - - } else { - - virtualLight = light.shadowCascadeArray[ n ]; - - } - - updateVirtualLight( light, n ); - - lights[ k ] = virtualLight; - k ++; - - } - - } else { - - lights[ k ] = light; - k ++; - - } - - } - - // render depth map - - for ( i = 0, il = lights.length; i < il; i ++ ) { - - light = lights[ i ]; - - if ( ! light.shadowMap ) { - - var shadowFilter = THREE.LinearFilter; - - if ( _renderer.shadowMapType === THREE.PCFSoftShadowMap ) { - - shadowFilter = THREE.NearestFilter; - - } - - var pars = { minFilter: shadowFilter, magFilter: shadowFilter, format: THREE.RGBAFormat }; - - light.shadowMap = new THREE.WebGLRenderTarget( light.shadowMapWidth, light.shadowMapHeight, pars ); - light.shadowMapSize = new THREE.Vector2( light.shadowMapWidth, light.shadowMapHeight ); - - light.shadowMatrix = new THREE.Matrix4(); - - } - - if ( ! light.shadowCamera ) { - - if ( light instanceof THREE.SpotLight ) { - - light.shadowCamera = new THREE.PerspectiveCamera( light.shadowCameraFov, light.shadowMapWidth / light.shadowMapHeight, light.shadowCameraNear, light.shadowCameraFar ); - - } else if ( light instanceof THREE.DirectionalLight ) { - - light.shadowCamera = new THREE.OrthographicCamera( light.shadowCameraLeft, light.shadowCameraRight, light.shadowCameraTop, light.shadowCameraBottom, light.shadowCameraNear, light.shadowCameraFar ); - - } else { - - console.error( "Unsupported light type for shadow" ); - continue; - - } - - scene.add( light.shadowCamera ); - - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - - } - - if ( light.shadowCameraVisible && ! light.cameraHelper ) { - - light.cameraHelper = new THREE.CameraHelper( light.shadowCamera ); - light.shadowCamera.add( light.cameraHelper ); - - } - - if ( light.isVirtual && virtualLight.originalCamera == camera ) { - - updateShadowCamera( camera, light ); - - } - - shadowMap = light.shadowMap; - shadowMatrix = light.shadowMatrix; - shadowCamera = light.shadowCamera; - - shadowCamera.position.setFromMatrixPosition( light.matrixWorld ); - _matrixPosition.setFromMatrixPosition( light.target.matrixWorld ); - shadowCamera.lookAt( _matrixPosition ); - shadowCamera.updateMatrixWorld(); - - shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld ); - - if ( light.cameraHelper ) light.cameraHelper.visible = light.shadowCameraVisible; - if ( light.shadowCameraVisible ) light.cameraHelper.update(); - - // compute shadow matrix - - shadowMatrix.set( 0.5, 0.0, 0.0, 0.5, - 0.0, 0.5, 0.0, 0.5, - 0.0, 0.0, 0.5, 0.5, - 0.0, 0.0, 0.0, 1.0 ); - - shadowMatrix.multiply( shadowCamera.projectionMatrix ); - shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); - - // update camera matrices and frustum - - _projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); - _frustum.setFromMatrix( _projScreenMatrix ); - - // render shadow map - - _renderer.setRenderTarget( shadowMap ); - _renderer.clear(); - - // set object matrices & frustum culling - - renderList = scene.__webglObjects; - - for ( j = 0, jl = renderList.length; j < jl; j ++ ) { - - webglObject = renderList[ j ]; - object = webglObject.object; - - webglObject.render = false; - - if ( object.visible && object.castShadow ) { - - if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.intersectsObject( object ) ) { - - object._modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); - - webglObject.render = true; - - } - - } - - } - - // render regular objects - - var objectMaterial, useMorphing, useSkinning; - - for ( j = 0, jl = renderList.length; j < jl; j ++ ) { - - webglObject = renderList[ j ]; - - if ( webglObject.render ) { - - object = webglObject.object; - buffer = webglObject.buffer; - - // culling is overriden globally for all objects - // while rendering depth map - - // need to deal with MeshFaceMaterial somehow - // in that case just use the first of material.materials for now - // (proper solution would require to break objects by materials - // similarly to regular rendering and then set corresponding - // depth materials per each chunk instead of just once per object) - - objectMaterial = getObjectMaterial( object ); - - useMorphing = object.geometry.morphTargets !== undefined && object.geometry.morphTargets.length > 0 && objectMaterial.morphTargets; - useSkinning = object instanceof THREE.SkinnedMesh && objectMaterial.skinning; - - if ( object.customDepthMaterial ) { - - material = object.customDepthMaterial; - - } else if ( useSkinning ) { - - material = useMorphing ? _depthMaterialMorphSkin : _depthMaterialSkin; - - } else if ( useMorphing ) { - - material = _depthMaterialMorph; - - } else { - - material = _depthMaterial; - - } - - _renderer.setMaterialFaces( objectMaterial ); - - if ( buffer instanceof THREE.BufferGeometry ) { - - _renderer.renderBufferDirect( shadowCamera, scene.__lights, fog, material, buffer, object ); - - } else { - - _renderer.renderBuffer( shadowCamera, scene.__lights, fog, material, buffer, object ); - - } - - } - - } - - // set matrices and render immediate objects - - renderList = scene.__webglObjectsImmediate; - - for ( j = 0, jl = renderList.length; j < jl; j ++ ) { - - webglObject = renderList[ j ]; - object = webglObject.object; - - if ( object.visible && object.castShadow ) { - - object._modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); - - _renderer.renderImmediateObject( shadowCamera, scene.__lights, fog, _depthMaterial, object ); - - } - - } - - } - - // restore GL state - - var clearColor = _renderer.getClearColor(), - clearAlpha = _renderer.getClearAlpha(); - - _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha ); - _gl.enable( _gl.BLEND ); - - if ( _renderer.shadowMapCullFace === THREE.CullFaceFront ) { - - _gl.cullFace( _gl.BACK ); - - } - - }; - - function createVirtualLight( light, cascade ) { - - var virtualLight = new THREE.DirectionalLight(); - - virtualLight.isVirtual = true; - - virtualLight.onlyShadow = true; - virtualLight.castShadow = true; - - virtualLight.shadowCameraNear = light.shadowCameraNear; - virtualLight.shadowCameraFar = light.shadowCameraFar; - - virtualLight.shadowCameraLeft = light.shadowCameraLeft; - virtualLight.shadowCameraRight = light.shadowCameraRight; - virtualLight.shadowCameraBottom = light.shadowCameraBottom; - virtualLight.shadowCameraTop = light.shadowCameraTop; - - virtualLight.shadowCameraVisible = light.shadowCameraVisible; - - virtualLight.shadowDarkness = light.shadowDarkness; - - virtualLight.shadowBias = light.shadowCascadeBias[ cascade ]; - virtualLight.shadowMapWidth = light.shadowCascadeWidth[ cascade ]; - virtualLight.shadowMapHeight = light.shadowCascadeHeight[ cascade ]; - - virtualLight.pointsWorld = []; - virtualLight.pointsFrustum = []; - - var pointsWorld = virtualLight.pointsWorld, - pointsFrustum = virtualLight.pointsFrustum; - - for ( var i = 0; i < 8; i ++ ) { - - pointsWorld[ i ] = new THREE.Vector3(); - pointsFrustum[ i ] = new THREE.Vector3(); - - } - - var nearZ = light.shadowCascadeNearZ[ cascade ]; - var farZ = light.shadowCascadeFarZ[ cascade ]; - - pointsFrustum[ 0 ].set( -1, -1, nearZ ); - pointsFrustum[ 1 ].set( 1, -1, nearZ ); - pointsFrustum[ 2 ].set( -1, 1, nearZ ); - pointsFrustum[ 3 ].set( 1, 1, nearZ ); - - pointsFrustum[ 4 ].set( -1, -1, farZ ); - pointsFrustum[ 5 ].set( 1, -1, farZ ); - pointsFrustum[ 6 ].set( -1, 1, farZ ); - pointsFrustum[ 7 ].set( 1, 1, farZ ); - - return virtualLight; - - } - - // Synchronize virtual light with the original light - - function updateVirtualLight( light, cascade ) { - - var virtualLight = light.shadowCascadeArray[ cascade ]; - - virtualLight.position.copy( light.position ); - virtualLight.target.position.copy( light.target.position ); - virtualLight.lookAt( virtualLight.target ); - - virtualLight.shadowCameraVisible = light.shadowCameraVisible; - virtualLight.shadowDarkness = light.shadowDarkness; - - virtualLight.shadowBias = light.shadowCascadeBias[ cascade ]; - - var nearZ = light.shadowCascadeNearZ[ cascade ]; - var farZ = light.shadowCascadeFarZ[ cascade ]; - - var pointsFrustum = virtualLight.pointsFrustum; - - pointsFrustum[ 0 ].z = nearZ; - pointsFrustum[ 1 ].z = nearZ; - pointsFrustum[ 2 ].z = nearZ; - pointsFrustum[ 3 ].z = nearZ; - - pointsFrustum[ 4 ].z = farZ; - pointsFrustum[ 5 ].z = farZ; - pointsFrustum[ 6 ].z = farZ; - pointsFrustum[ 7 ].z = farZ; - - } - - // Fit shadow camera's ortho frustum to camera frustum - - function updateShadowCamera( camera, light ) { - - var shadowCamera = light.shadowCamera, - pointsFrustum = light.pointsFrustum, - pointsWorld = light.pointsWorld; - - _min.set( Infinity, Infinity, Infinity ); - _max.set( -Infinity, -Infinity, -Infinity ); - - for ( var i = 0; i < 8; i ++ ) { - - var p = pointsWorld[ i ]; - - p.copy( pointsFrustum[ i ] ); - THREE.ShadowMapPlugin.__projector.unprojectVector( p, camera ); - - p.applyMatrix4( shadowCamera.matrixWorldInverse ); - - if ( p.x < _min.x ) _min.x = p.x; - if ( p.x > _max.x ) _max.x = p.x; - - if ( p.y < _min.y ) _min.y = p.y; - if ( p.y > _max.y ) _max.y = p.y; - - if ( p.z < _min.z ) _min.z = p.z; - if ( p.z > _max.z ) _max.z = p.z; - - } - - shadowCamera.left = _min.x; - shadowCamera.right = _max.x; - shadowCamera.top = _max.y; - shadowCamera.bottom = _min.y; - - // can't really fit near/far - //shadowCamera.near = _min.z; - //shadowCamera.far = _max.z; - - shadowCamera.updateProjectionMatrix(); - - } - - // For the moment just ignore objects that have multiple materials with different animation methods - // Only the first material will be taken into account for deciding which depth material to use for shadow maps - - function getObjectMaterial( object ) { - - return object.material instanceof THREE.MeshFaceMaterial - ? object.material.materials[ 0 ] - : object.material; - - }; - -}; - -THREE.ShadowMapPlugin.__projector = new THREE.Projector(); - -/** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.SpritePlugin = function () { - - var _gl, _renderer, _texture; - - var vertices, faces, vertexBuffer, elementBuffer; - var program, attributes, uniforms; - - this.init = function ( renderer ) { - - _gl = renderer.context; - _renderer = renderer; - - vertices = new Float32Array( [ - - 0.5, - 0.5, 0, 0, - 0.5, - 0.5, 1, 0, - 0.5, 0.5, 1, 1, - - 0.5, 0.5, 0, 1 - ] ); - - faces = new Uint16Array( [ - 0, 1, 2, - 0, 2, 3 - ] ); - - vertexBuffer = _gl.createBuffer(); - elementBuffer = _gl.createBuffer(); - - _gl.bindBuffer( _gl.ARRAY_BUFFER, vertexBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, vertices, _gl.STATIC_DRAW ); - - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, elementBuffer ); - _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faces, _gl.STATIC_DRAW ); - - program = createProgram(); - - attributes = { - position: _gl.getAttribLocation ( program, 'position' ), - uv: _gl.getAttribLocation ( program, 'uv' ) - }; - - uniforms = { - uvOffset: _gl.getUniformLocation( program, 'uvOffset' ), - uvScale: _gl.getUniformLocation( program, 'uvScale' ), - - rotation: _gl.getUniformLocation( program, 'rotation' ), - scale: _gl.getUniformLocation( program, 'scale' ), - - color: _gl.getUniformLocation( program, 'color' ), - map: _gl.getUniformLocation( program, 'map' ), - opacity: _gl.getUniformLocation( program, 'opacity' ), - - modelViewMatrix: _gl.getUniformLocation( program, 'modelViewMatrix' ), - projectionMatrix: _gl.getUniformLocation( program, 'projectionMatrix' ), - - fogType: _gl.getUniformLocation( program, 'fogType' ), - fogDensity: _gl.getUniformLocation( program, 'fogDensity' ), - fogNear: _gl.getUniformLocation( program, 'fogNear' ), - fogFar: _gl.getUniformLocation( program, 'fogFar' ), - fogColor: _gl.getUniformLocation( program, 'fogColor' ), - - alphaTest: _gl.getUniformLocation( program, 'alphaTest' ) - }; - - var canvas = document.createElement( 'canvas' ); - canvas.width = 8; - canvas.height = 8; - - var context = canvas.getContext( '2d' ); - context.fillStyle = '#ffffff'; - context.fillRect( 0, 0, canvas.width, canvas.height ); - - _texture = new THREE.Texture( canvas ); - _texture.needsUpdate = true; - - }; - - this.render = function ( scene, camera, viewportWidth, viewportHeight ) { - - var sprites = scene.__webglSprites, - nSprites = sprites.length; - - if ( ! nSprites ) return; - - // setup gl - - _gl.useProgram( program ); - - _gl.enableVertexAttribArray( attributes.position ); - _gl.enableVertexAttribArray( attributes.uv ); - - _gl.disable( _gl.CULL_FACE ); - _gl.enable( _gl.BLEND ); - - _gl.bindBuffer( _gl.ARRAY_BUFFER, vertexBuffer ); - _gl.vertexAttribPointer( attributes.position, 2, _gl.FLOAT, false, 2 * 8, 0 ); - _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 ); - - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, elementBuffer ); - - _gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements ); - - _gl.activeTexture( _gl.TEXTURE0 ); - _gl.uniform1i( uniforms.map, 0 ); - - var oldFogType = 0; - var sceneFogType = 0; - var fog = scene.fog; - - if ( fog ) { - - _gl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b ); - - if ( fog instanceof THREE.Fog ) { - - _gl.uniform1f( uniforms.fogNear, fog.near ); - _gl.uniform1f( uniforms.fogFar, fog.far ); - - _gl.uniform1i( uniforms.fogType, 1 ); - oldFogType = 1; - sceneFogType = 1; - - } else if ( fog instanceof THREE.FogExp2 ) { - - _gl.uniform1f( uniforms.fogDensity, fog.density ); - - _gl.uniform1i( uniforms.fogType, 2 ); - oldFogType = 2; - sceneFogType = 2; - - } - - } else { - - _gl.uniform1i( uniforms.fogType, 0 ); - oldFogType = 0; - sceneFogType = 0; - - } - - - // update positions and sort - - var i, sprite, material, fogType, scale = []; - - for( i = 0; i < nSprites; i ++ ) { - - sprite = sprites[ i ]; - material = sprite.material; - - if ( sprite.visible === false ) continue; - - sprite._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld ); - sprite.z = - sprite._modelViewMatrix.elements[ 14 ]; - - } - - sprites.sort( painterSortStable ); - - // render all sprites - - for( i = 0; i < nSprites; i ++ ) { - - sprite = sprites[ i ]; - - if ( sprite.visible === false ) continue; - - material = sprite.material; - - _gl.uniform1f( uniforms.alphaTest, material.alphaTest ); - _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite._modelViewMatrix.elements ); - - scale[ 0 ] = sprite.scale.x; - scale[ 1 ] = sprite.scale.y; - - if ( scene.fog && material.fog ) { - - fogType = sceneFogType; - - } else { - - fogType = 0; - - } - - if ( oldFogType !== fogType ) { - - _gl.uniform1i( uniforms.fogType, fogType ); - oldFogType = fogType; - - } - - if ( material.map !== null ) { - - _gl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y ); - _gl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y ); - - } else { - - _gl.uniform2f( uniforms.uvOffset, 0, 0 ); - _gl.uniform2f( uniforms.uvScale, 1, 1 ); - - } - - _gl.uniform1f( uniforms.opacity, material.opacity ); - _gl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b ); - - _gl.uniform1f( uniforms.rotation, material.rotation ); - _gl.uniform2fv( uniforms.scale, scale ); - - _renderer.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst ); - _renderer.setDepthTest( material.depthTest ); - _renderer.setDepthWrite( material.depthWrite ); - - if ( material.map && material.map.image && material.map.image.width ) { - - _renderer.setTexture( material.map, 0 ); - - } else { - - _renderer.setTexture( _texture, 0 ); - - } - - _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 ); - - } - - // restore gl - - _gl.enable( _gl.CULL_FACE ); - - }; - - function createProgram () { - - var program = _gl.createProgram(); - - var vertexShader = _gl.createShader( _gl.VERTEX_SHADER ); - var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER ); - - _gl.shaderSource( vertexShader, [ - - 'precision ' + _renderer.getPrecision() + ' float;', - - 'uniform mat4 modelViewMatrix;', - 'uniform mat4 projectionMatrix;', - 'uniform float rotation;', - 'uniform vec2 scale;', - 'uniform vec2 uvOffset;', - 'uniform vec2 uvScale;', - - 'attribute vec2 position;', - 'attribute vec2 uv;', - - 'varying vec2 vUV;', - - 'void main() {', - - 'vUV = uvOffset + uv * uvScale;', - - 'vec2 alignedPosition = position * scale;', - - 'vec2 rotatedPosition;', - 'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;', - 'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;', - - 'vec4 finalPosition;', - - 'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );', - 'finalPosition.xy += rotatedPosition;', - 'finalPosition = projectionMatrix * finalPosition;', - - 'gl_Position = finalPosition;', - - '}' - - ].join( '\n' ) ); - - _gl.shaderSource( fragmentShader, [ - - 'precision ' + _renderer.getPrecision() + ' float;', - - 'uniform vec3 color;', - 'uniform sampler2D map;', - 'uniform float opacity;', - - 'uniform int fogType;', - 'uniform vec3 fogColor;', - 'uniform float fogDensity;', - 'uniform float fogNear;', - 'uniform float fogFar;', - 'uniform float alphaTest;', - - 'varying vec2 vUV;', - - 'void main() {', - - 'vec4 texture = texture2D( map, vUV );', - - 'if ( texture.a < alphaTest ) discard;', - - 'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );', - - 'if ( fogType > 0 ) {', - - 'float depth = gl_FragCoord.z / gl_FragCoord.w;', - 'float fogFactor = 0.0;', - - 'if ( fogType == 1 ) {', - - 'fogFactor = smoothstep( fogNear, fogFar, depth );', - - '} else {', - - 'const float LOG2 = 1.442695;', - 'float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );', - 'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );', - - '}', - - 'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );', - - '}', - - '}' - - ].join( '\n' ) ); - - _gl.compileShader( vertexShader ); - _gl.compileShader( fragmentShader ); - - _gl.attachShader( program, vertexShader ); - _gl.attachShader( program, fragmentShader ); - - _gl.linkProgram( program ); - - return program; - - }; - - function painterSortStable ( a, b ) { - - if ( a.z !== b.z ) { - - return b.z - a.z; - - } else { - - return b.id - a.id; - - } - - }; - -}; - -/** - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.DepthPassPlugin = function () { - - this.enabled = false; - this.renderTarget = null; - - var _gl, - _renderer, - _depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin, - - _frustum = new THREE.Frustum(), - _projScreenMatrix = new THREE.Matrix4(); - - this.init = function ( renderer ) { - - _gl = renderer.context; - _renderer = renderer; - - var depthShader = THREE.ShaderLib[ "depthRGBA" ]; - var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms ); - - _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } ); - _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } ); - _depthMaterialSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, skinning: true } ); - _depthMaterialMorphSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true, skinning: true } ); - - _depthMaterial._shadowPass = true; - _depthMaterialMorph._shadowPass = true; - _depthMaterialSkin._shadowPass = true; - _depthMaterialMorphSkin._shadowPass = true; - - }; - - this.render = function ( scene, camera ) { - - if ( ! this.enabled ) return; - - this.update( scene, camera ); - - }; - - this.update = function ( scene, camera ) { - - var i, il, j, jl, n, - - program, buffer, material, - webglObject, object, light, - renderList, - - fog = null; - - // set GL state for depth map - - _gl.clearColor( 1, 1, 1, 1 ); - _gl.disable( _gl.BLEND ); - - _renderer.setDepthTest( true ); - - // update scene - - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - - // update camera matrices and frustum - - camera.matrixWorldInverse.getInverse( camera.matrixWorld ); - - _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); - _frustum.setFromMatrix( _projScreenMatrix ); - - // render depth map - - _renderer.setRenderTarget( this.renderTarget ); - _renderer.clear(); - - // set object matrices & frustum culling - - renderList = scene.__webglObjects; - - for ( j = 0, jl = renderList.length; j < jl; j ++ ) { - - webglObject = renderList[ j ]; - object = webglObject.object; - - webglObject.render = false; - - if ( object.visible ) { - - if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.intersectsObject( object ) ) { - - object._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); - - webglObject.render = true; - - } - + return this.setAttribute(name, attribute); + }, + addDrawCall: function addDrawCall(start, count, indexOffset) { + if (indexOffset !== undefined) { + console.warn('THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.'); } + console.warn('THREE.BufferGeometry: .addDrawCall() is now .addGroup().'); + this.addGroup(start, count); + }, + clearDrawCalls: function clearDrawCalls() { + console.warn('THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().'); + this.clearGroups(); + }, + computeTangents: function computeTangents() { + console.warn('THREE.BufferGeometry: .computeTangents() has been removed.'); + }, + computeOffsets: function computeOffsets() { + console.warn('THREE.BufferGeometry: .computeOffsets() has been removed.'); + }, + removeAttribute: function removeAttribute(name) { + console.warn('THREE.BufferGeometry: .removeAttribute() has been renamed to .deleteAttribute().'); + return this.deleteAttribute(name); + }, + applyMatrix: function applyMatrix(matrix) { + console.warn('THREE.BufferGeometry: .applyMatrix() has been renamed to .applyMatrix4().'); + return this.applyMatrix4(matrix); } + }); + Object.defineProperties(BufferGeometry.prototype, { + drawcalls: { + get: function get() { + console.error('THREE.BufferGeometry: .drawcalls has been renamed to .groups.'); + return this.groups; + } + }, + offsets: { + get: function get() { + console.warn('THREE.BufferGeometry: .offsets has been renamed to .groups.'); + return this.groups; + } + } + }); + Object.defineProperties(InstancedBufferGeometry.prototype, { + maxInstancedCount: { + get: function get() { + console.warn('THREE.InstancedBufferGeometry: .maxInstancedCount has been renamed to .instanceCount.'); + return this.instanceCount; + }, + set: function set(value) { + console.warn('THREE.InstancedBufferGeometry: .maxInstancedCount has been renamed to .instanceCount.'); + this.instanceCount = value; + } + } + }); + Object.defineProperties(Raycaster.prototype, { + linePrecision: { + get: function get() { + console.warn('THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.'); + return this.params.Line.threshold; + }, + set: function set(value) { + console.warn('THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.'); + this.params.Line.threshold = value; + } + } + }); + Object.defineProperties(InterleavedBuffer.prototype, { + dynamic: { + get: function get() { + console.warn('THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.'); + return this.usage === DynamicDrawUsage; + }, + set: function set(value) { + console.warn('THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.'); + this.setUsage(value); + } + } + }); + Object.assign(InterleavedBuffer.prototype, { + setDynamic: function setDynamic(value) { + console.warn('THREE.InterleavedBuffer: .setDynamic() has been deprecated. Use .setUsage() instead.'); + this.setUsage(value === true ? DynamicDrawUsage : StaticDrawUsage); + return this; + }, + setArray: function setArray() + /* array */ + { + console.error('THREE.InterleavedBuffer: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers'); + } + }); // - // render regular objects - - var objectMaterial, useMorphing, useSkinning; - - for ( j = 0, jl = renderList.length; j < jl; j ++ ) { - - webglObject = renderList[ j ]; - - if ( webglObject.render ) { - - object = webglObject.object; - buffer = webglObject.buffer; - - // todo: create proper depth material for particles - - if ( object instanceof THREE.ParticleSystem && !object.customDepthMaterial ) continue; - - objectMaterial = getObjectMaterial( object ); - - if ( objectMaterial ) _renderer.setMaterialFaces( object.material ); - - useMorphing = object.geometry.morphTargets !== undefined && object.geometry.morphTargets.length > 0 && objectMaterial.morphTargets; - useSkinning = object instanceof THREE.SkinnedMesh && objectMaterial.skinning; - - if ( object.customDepthMaterial ) { - - material = object.customDepthMaterial; - - } else if ( useSkinning ) { - - material = useMorphing ? _depthMaterialMorphSkin : _depthMaterialSkin; - - } else if ( useMorphing ) { - - material = _depthMaterialMorph; - - } else { - - material = _depthMaterial; - - } - - if ( buffer instanceof THREE.BufferGeometry ) { - - _renderer.renderBufferDirect( camera, scene.__lights, fog, material, buffer, object ); - - } else { - - _renderer.renderBuffer( camera, scene.__lights, fog, material, buffer, object ); + Object.assign(ExtrudeBufferGeometry.prototype, { + getArrays: function getArrays() { + console.error('THREE.ExtrudeBufferGeometry: .getArrays() has been removed.'); + }, + addShapeList: function addShapeList() { + console.error('THREE.ExtrudeBufferGeometry: .addShapeList() has been removed.'); + }, + addShape: function addShape() { + console.error('THREE.ExtrudeBufferGeometry: .addShape() has been removed.'); + } + }); // - } + Object.assign(Scene.prototype, { + dispose: function dispose() { + console.error('THREE.Scene: .dispose() has been removed.'); + } + }); // + Object.defineProperties(Uniform.prototype, { + dynamic: { + set: function set() { + console.warn('THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.'); + } + }, + onUpdate: { + value: function value() { + console.warn('THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.'); + return this; } - } + }); // - // set matrices and render immediate objects + Object.defineProperties(Material.prototype, { + wrapAround: { + get: function get() { + console.warn('THREE.Material: .wrapAround has been removed.'); + }, + set: function set() { + console.warn('THREE.Material: .wrapAround has been removed.'); + } + }, + overdraw: { + get: function get() { + console.warn('THREE.Material: .overdraw has been removed.'); + }, + set: function set() { + console.warn('THREE.Material: .overdraw has been removed.'); + } + }, + wrapRGB: { + get: function get() { + console.warn('THREE.Material: .wrapRGB has been removed.'); + return new Color(); + } + }, + shading: { + get: function get() { + console.error('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.'); + }, + set: function set(value) { + console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.'); + this.flatShading = value === FlatShading; + } + }, + stencilMask: { + get: function get() { + console.warn('THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.'); + return this.stencilFuncMask; + }, + set: function set(value) { + console.warn('THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.'); + this.stencilFuncMask = value; + } + } + }); + Object.defineProperties(MeshPhongMaterial.prototype, { + metal: { + get: function get() { + console.warn('THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.'); + return false; + }, + set: function set() { + console.warn('THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead'); + } + } + }); + Object.defineProperties(MeshPhysicalMaterial.prototype, { + transparency: { + get: function get() { + console.warn('THREE.MeshPhysicalMaterial: .transparency has been renamed to .transmission.'); + return this.transmission; + }, + set: function set(value) { + console.warn('THREE.MeshPhysicalMaterial: .transparency has been renamed to .transmission.'); + this.transmission = value; + } + } + }); + Object.defineProperties(ShaderMaterial.prototype, { + derivatives: { + get: function get() { + console.warn('THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.'); + return this.extensions.derivatives; + }, + set: function set(value) { + console.warn('THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.'); + this.extensions.derivatives = value; + } + } + }); // + + Object.assign(WebGLRenderer.prototype, { + clearTarget: function clearTarget(renderTarget, color, depth, stencil) { + console.warn('THREE.WebGLRenderer: .clearTarget() has been deprecated. Use .setRenderTarget() and .clear() instead.'); + this.setRenderTarget(renderTarget); + this.clear(color, depth, stencil); + }, + animate: function animate(callback) { + console.warn('THREE.WebGLRenderer: .animate() is now .setAnimationLoop().'); + this.setAnimationLoop(callback); + }, + getCurrentRenderTarget: function getCurrentRenderTarget() { + console.warn('THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().'); + return this.getRenderTarget(); + }, + getMaxAnisotropy: function getMaxAnisotropy() { + console.warn('THREE.WebGLRenderer: .getMaxAnisotropy() is now .capabilities.getMaxAnisotropy().'); + return this.capabilities.getMaxAnisotropy(); + }, + getPrecision: function getPrecision() { + console.warn('THREE.WebGLRenderer: .getPrecision() is now .capabilities.precision.'); + return this.capabilities.precision; + }, + resetGLState: function resetGLState() { + console.warn('THREE.WebGLRenderer: .resetGLState() is now .state.reset().'); + return this.state.reset(); + }, + supportsFloatTextures: function supportsFloatTextures() { + console.warn('THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).'); + return this.extensions.get('OES_texture_float'); + }, + supportsHalfFloatTextures: function supportsHalfFloatTextures() { + console.warn('THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).'); + return this.extensions.get('OES_texture_half_float'); + }, + supportsStandardDerivatives: function supportsStandardDerivatives() { + console.warn('THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).'); + return this.extensions.get('OES_standard_derivatives'); + }, + supportsCompressedTextureS3TC: function supportsCompressedTextureS3TC() { + console.warn('THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).'); + return this.extensions.get('WEBGL_compressed_texture_s3tc'); + }, + supportsCompressedTexturePVRTC: function supportsCompressedTexturePVRTC() { + console.warn('THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).'); + return this.extensions.get('WEBGL_compressed_texture_pvrtc'); + }, + supportsBlendMinMax: function supportsBlendMinMax() { + console.warn('THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).'); + return this.extensions.get('EXT_blend_minmax'); + }, + supportsVertexTextures: function supportsVertexTextures() { + console.warn('THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.'); + return this.capabilities.vertexTextures; + }, + supportsInstancedArrays: function supportsInstancedArrays() { + console.warn('THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).'); + return this.extensions.get('ANGLE_instanced_arrays'); + }, + enableScissorTest: function enableScissorTest(boolean) { + console.warn('THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().'); + this.setScissorTest(boolean); + }, + initMaterial: function initMaterial() { + console.warn('THREE.WebGLRenderer: .initMaterial() has been removed.'); + }, + addPrePlugin: function addPrePlugin() { + console.warn('THREE.WebGLRenderer: .addPrePlugin() has been removed.'); + }, + addPostPlugin: function addPostPlugin() { + console.warn('THREE.WebGLRenderer: .addPostPlugin() has been removed.'); + }, + updateShadowMap: function updateShadowMap() { + console.warn('THREE.WebGLRenderer: .updateShadowMap() has been removed.'); + }, + setFaceCulling: function setFaceCulling() { + console.warn('THREE.WebGLRenderer: .setFaceCulling() has been removed.'); + }, + allocTextureUnit: function allocTextureUnit() { + console.warn('THREE.WebGLRenderer: .allocTextureUnit() has been removed.'); + }, + setTexture: function setTexture() { + console.warn('THREE.WebGLRenderer: .setTexture() has been removed.'); + }, + setTexture2D: function setTexture2D() { + console.warn('THREE.WebGLRenderer: .setTexture2D() has been removed.'); + }, + setTextureCube: function setTextureCube() { + console.warn('THREE.WebGLRenderer: .setTextureCube() has been removed.'); + }, + getActiveMipMapLevel: function getActiveMipMapLevel() { + console.warn('THREE.WebGLRenderer: .getActiveMipMapLevel() is now .getActiveMipmapLevel().'); + return this.getActiveMipmapLevel(); + } + }); + Object.defineProperties(WebGLRenderer.prototype, { + shadowMapEnabled: { + get: function get() { + return this.shadowMap.enabled; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.'); + this.shadowMap.enabled = value; + } + }, + shadowMapType: { + get: function get() { + return this.shadowMap.type; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.'); + this.shadowMap.type = value; + } + }, + shadowMapCullFace: { + get: function get() { + console.warn('THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.'); + return undefined; + }, + set: function set() + /* value */ + { + console.warn('THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.'); + } + }, + context: { + get: function get() { + console.warn('THREE.WebGLRenderer: .context has been removed. Use .getContext() instead.'); + return this.getContext(); + } + }, + vr: { + get: function get() { + console.warn('THREE.WebGLRenderer: .vr has been renamed to .xr'); + return this.xr; + } + }, + gammaInput: { + get: function get() { + console.warn('THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.'); + return false; + }, + set: function set() { + console.warn('THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.'); + } + }, + gammaOutput: { + get: function get() { + console.warn('THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.'); + return false; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.'); + this.outputEncoding = value === true ? sRGBEncoding : LinearEncoding; + } + }, + toneMappingWhitePoint: { + get: function get() { + console.warn('THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.'); + return 1.0; + }, + set: function set() { + console.warn('THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.'); + } + } + }); + Object.defineProperties(WebGLShadowMap.prototype, { + cullFace: { + get: function get() { + console.warn('THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.'); + return undefined; + }, + set: function set() + /* cullFace */ + { + console.warn('THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.'); + } + }, + renderReverseSided: { + get: function get() { + console.warn('THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.'); + return undefined; + }, + set: function set() { + console.warn('THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.'); + } + }, + renderSingleSided: { + get: function get() { + console.warn('THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.'); + return undefined; + }, + set: function set() { + console.warn('THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.'); + } + } + }); + function WebGLRenderTargetCube(width, height, options) { + console.warn('THREE.WebGLRenderTargetCube( width, height, options ) is now WebGLCubeRenderTarget( size, options ).'); + return new WebGLCubeRenderTarget(width, options); + } // + + Object.defineProperties(WebGLRenderTarget.prototype, { + wrapS: { + get: function get() { + console.warn('THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.'); + return this.texture.wrapS; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.'); + this.texture.wrapS = value; + } + }, + wrapT: { + get: function get() { + console.warn('THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.'); + return this.texture.wrapT; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.'); + this.texture.wrapT = value; + } + }, + magFilter: { + get: function get() { + console.warn('THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.'); + return this.texture.magFilter; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.'); + this.texture.magFilter = value; + } + }, + minFilter: { + get: function get() { + console.warn('THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.'); + return this.texture.minFilter; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.'); + this.texture.minFilter = value; + } + }, + anisotropy: { + get: function get() { + console.warn('THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.'); + return this.texture.anisotropy; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.'); + this.texture.anisotropy = value; + } + }, + offset: { + get: function get() { + console.warn('THREE.WebGLRenderTarget: .offset is now .texture.offset.'); + return this.texture.offset; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderTarget: .offset is now .texture.offset.'); + this.texture.offset = value; + } + }, + repeat: { + get: function get() { + console.warn('THREE.WebGLRenderTarget: .repeat is now .texture.repeat.'); + return this.texture.repeat; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderTarget: .repeat is now .texture.repeat.'); + this.texture.repeat = value; + } + }, + format: { + get: function get() { + console.warn('THREE.WebGLRenderTarget: .format is now .texture.format.'); + return this.texture.format; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderTarget: .format is now .texture.format.'); + this.texture.format = value; + } + }, + type: { + get: function get() { + console.warn('THREE.WebGLRenderTarget: .type is now .texture.type.'); + return this.texture.type; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderTarget: .type is now .texture.type.'); + this.texture.type = value; + } + }, + generateMipmaps: { + get: function get() { + console.warn('THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.'); + return this.texture.generateMipmaps; + }, + set: function set(value) { + console.warn('THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.'); + this.texture.generateMipmaps = value; + } + } + }); // + + Object.defineProperties(Audio.prototype, { + load: { + value: function value(file) { + console.warn('THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.'); + var scope = this; + var audioLoader = new AudioLoader(); + audioLoader.load(file, function (buffer) { + scope.setBuffer(buffer); + }); + return this; + } + }, + startTime: { + set: function set() { + console.warn('THREE.Audio: .startTime is now .play( delay ).'); + } + } + }); - renderList = scene.__webglObjectsImmediate; + AudioAnalyser.prototype.getData = function () { + console.warn('THREE.AudioAnalyser: .getData() is now .getFrequencyData().'); + return this.getFrequencyData(); + }; // - for ( j = 0, jl = renderList.length; j < jl; j ++ ) { - webglObject = renderList[ j ]; - object = webglObject.object; + CubeCamera.prototype.updateCubeMap = function (renderer, scene) { + console.warn('THREE.CubeCamera: .updateCubeMap() is now .update().'); + return this.update(renderer, scene); + }; - if ( object.visible ) { + CubeCamera.prototype.clear = function (renderer, color, depth, stencil) { + console.warn('THREE.CubeCamera: .clear() is now .renderTarget.clear().'); + return this.renderTarget.clear(renderer, color, depth, stencil); + }; // - object._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); - _renderer.renderImmediateObject( camera, scene.__lights, fog, _depthMaterial, object ); + var GeometryUtils = { + merge: function merge(geometry1, geometry2, materialIndexOffset) { + console.warn('THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.'); + var matrix; + if (geometry2.isMesh) { + geometry2.matrixAutoUpdate && geometry2.updateMatrix(); + matrix = geometry2.matrix; + geometry2 = geometry2.geometry; } + geometry1.merge(geometry2, matrix, materialIndexOffset); + }, + center: function center(geometry) { + console.warn('THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.'); + return geometry.center(); } - - // restore GL state - - var clearColor = _renderer.getClearColor(), - clearAlpha = _renderer.getClearAlpha(); - - _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha ); - _gl.enable( _gl.BLEND ); - }; - - // For the moment just ignore objects that have multiple materials with different animation methods - // Only the first material will be taken into account for deciding which depth material to use - - function getObjectMaterial( object ) { - - return object.material instanceof THREE.MeshFaceMaterial - ? object.material.materials[ 0 ] - : object.material; - + ImageUtils.crossOrigin = undefined; + + ImageUtils.loadTexture = function (url, mapping, onLoad, onError) { + console.warn('THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.'); + var loader = new TextureLoader(); + loader.setCrossOrigin(this.crossOrigin); + var texture = loader.load(url, onLoad, undefined, onError); + if (mapping) texture.mapping = mapping; + return texture; }; -}; - - -/** - * @author mikael emtinger / http://gomo.se/ - */ - -THREE.ShaderFlares = { - - 'lensFlareVertexTexture': { - - vertexShader: [ - - "uniform lowp int renderType;", - - "uniform vec3 screenPosition;", - "uniform vec2 scale;", - "uniform float rotation;", - - "uniform sampler2D occlusionMap;", - - "attribute vec2 position;", - "attribute vec2 uv;", - - "varying vec2 vUV;", - "varying float vVisibility;", - - "void main() {", - - "vUV = uv;", - - "vec2 pos = position;", - - "if( renderType == 2 ) {", - - "vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );", - - "vVisibility = visibility.r / 9.0;", - "vVisibility *= 1.0 - visibility.g / 9.0;", - "vVisibility *= visibility.b / 9.0;", - "vVisibility *= 1.0 - visibility.a / 9.0;", - - "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;", - "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;", - - "}", - - "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform lowp int renderType;", - - "uniform sampler2D map;", - "uniform float opacity;", - "uniform vec3 color;", - - "varying vec2 vUV;", - "varying float vVisibility;", - - "void main() {", - - // pink square - - "if( renderType == 0 ) {", - - "gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );", - - // restore - - "} else if( renderType == 1 ) {", - - "gl_FragColor = texture2D( map, vUV );", - - // flare - - "} else {", - - "vec4 texture = texture2D( map, vUV );", - "texture.a *= opacity * vVisibility;", - "gl_FragColor = texture;", - "gl_FragColor.rgb *= color;", - - "}", - - "}" - ].join( "\n" ) - - }, - - - 'lensFlare': { - - vertexShader: [ - - "uniform lowp int renderType;", - - "uniform vec3 screenPosition;", - "uniform vec2 scale;", - "uniform float rotation;", - - "attribute vec2 position;", - "attribute vec2 uv;", - - "varying vec2 vUV;", - - "void main() {", - - "vUV = uv;", - - "vec2 pos = position;", - - "if( renderType == 2 ) {", - - "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;", - "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;", - - "}", - - "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "precision mediump float;", - - "uniform lowp int renderType;", - - "uniform sampler2D map;", - "uniform sampler2D occlusionMap;", - "uniform float opacity;", - "uniform vec3 color;", - - "varying vec2 vUV;", - - "void main() {", - - // pink square - - "if( renderType == 0 ) {", - - "gl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );", - - // restore - - "} else if( renderType == 1 ) {", - - "gl_FragColor = texture2D( map, vUV );", - - // flare - - "} else {", - - "float visibility = texture2D( occlusionMap, vec2( 0.5, 0.1 ) ).a;", - "visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) ).a;", - "visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) ).a;", - "visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) ).a;", - "visibility = ( 1.0 - visibility / 4.0 );", - - "vec4 texture = texture2D( map, vUV );", - "texture.a *= opacity * visibility;", - "gl_FragColor = texture;", - "gl_FragColor.rgb *= color;", + ImageUtils.loadTextureCube = function (urls, mapping, onLoad, onError) { + console.warn('THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.'); + var loader = new CubeTextureLoader(); + loader.setCrossOrigin(this.crossOrigin); + var texture = loader.load(urls, onLoad, undefined, onError); + if (mapping) texture.mapping = mapping; + return texture; + }; - "}", + ImageUtils.loadCompressedTexture = function () { + console.error('THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.'); + }; - "}" + ImageUtils.loadCompressedTextureCube = function () { + console.error('THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.'); + }; // - ].join( "\n" ) - } + function CanvasRenderer() { + console.error('THREE.CanvasRenderer has been removed'); + } // -}; + function JSONLoader() { + console.error('THREE.JSONLoader has been removed.'); + } // + var SceneUtils = { + createMultiMaterialObject: function createMultiMaterialObject() + /* geometry, materials */ + { + console.error('THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js'); + }, + detach: function detach() + /* child, parent, scene */ + { + console.error('THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js'); + }, + attach: function attach() + /* child, scene, parent */ + { + console.error('THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js'); + } + }; // + + function LensFlare() { + console.error('THREE.LensFlare has been moved to /examples/jsm/objects/Lensflare.js'); + } + + if (typeof __THREE_DEVTOOLS__ !== 'undefined') { + /* eslint-disable no-undef */ + __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('register', { + detail: { + revision: REVISION + } + })); + /* eslint-enable no-undef */ + + } + + exports.ACESFilmicToneMapping = ACESFilmicToneMapping; + exports.AddEquation = AddEquation; + exports.AddOperation = AddOperation; + exports.AdditiveAnimationBlendMode = AdditiveAnimationBlendMode; + exports.AdditiveBlending = AdditiveBlending; + exports.AlphaFormat = AlphaFormat; + exports.AlwaysDepth = AlwaysDepth; + exports.AlwaysStencilFunc = AlwaysStencilFunc; + exports.AmbientLight = AmbientLight; + exports.AmbientLightProbe = AmbientLightProbe; + exports.AnimationClip = AnimationClip; + exports.AnimationLoader = AnimationLoader; + exports.AnimationMixer = AnimationMixer; + exports.AnimationObjectGroup = AnimationObjectGroup; + exports.AnimationUtils = AnimationUtils; + exports.ArcCurve = ArcCurve; + exports.ArrayCamera = ArrayCamera; + exports.ArrowHelper = ArrowHelper; + exports.Audio = Audio; + exports.AudioAnalyser = AudioAnalyser; + exports.AudioContext = AudioContext; + exports.AudioListener = AudioListener; + exports.AudioLoader = AudioLoader; + exports.AxesHelper = AxesHelper; + exports.AxisHelper = AxisHelper; + exports.BackSide = BackSide; + exports.BasicDepthPacking = BasicDepthPacking; + exports.BasicShadowMap = BasicShadowMap; + exports.BinaryTextureLoader = BinaryTextureLoader; + exports.Bone = Bone; + exports.BooleanKeyframeTrack = BooleanKeyframeTrack; + exports.BoundingBoxHelper = BoundingBoxHelper; + exports.Box2 = Box2; + exports.Box3 = Box3; + exports.Box3Helper = Box3Helper; + exports.BoxBufferGeometry = BoxBufferGeometry; + exports.BoxGeometry = BoxGeometry; + exports.BoxHelper = BoxHelper; + exports.BufferAttribute = BufferAttribute; + exports.BufferGeometry = BufferGeometry; + exports.BufferGeometryLoader = BufferGeometryLoader; + exports.ByteType = ByteType; + exports.Cache = Cache; + exports.Camera = Camera; + exports.CameraHelper = CameraHelper; + exports.CanvasRenderer = CanvasRenderer; + exports.CanvasTexture = CanvasTexture; + exports.CatmullRomCurve3 = CatmullRomCurve3; + exports.CineonToneMapping = CineonToneMapping; + exports.CircleBufferGeometry = CircleBufferGeometry; + exports.CircleGeometry = CircleGeometry; + exports.ClampToEdgeWrapping = ClampToEdgeWrapping; + exports.Clock = Clock; + exports.ClosedSplineCurve3 = ClosedSplineCurve3; + exports.Color = Color; + exports.ColorKeyframeTrack = ColorKeyframeTrack; + exports.CompressedTexture = CompressedTexture; + exports.CompressedTextureLoader = CompressedTextureLoader; + exports.ConeBufferGeometry = ConeBufferGeometry; + exports.ConeGeometry = ConeGeometry; + exports.CubeCamera = CubeCamera; + exports.CubeGeometry = BoxGeometry; + exports.CubeReflectionMapping = CubeReflectionMapping; + exports.CubeRefractionMapping = CubeRefractionMapping; + exports.CubeTexture = CubeTexture; + exports.CubeTextureLoader = CubeTextureLoader; + exports.CubeUVReflectionMapping = CubeUVReflectionMapping; + exports.CubeUVRefractionMapping = CubeUVRefractionMapping; + exports.CubicBezierCurve = CubicBezierCurve; + exports.CubicBezierCurve3 = CubicBezierCurve3; + exports.CubicInterpolant = CubicInterpolant; + exports.CullFaceBack = CullFaceBack; + exports.CullFaceFront = CullFaceFront; + exports.CullFaceFrontBack = CullFaceFrontBack; + exports.CullFaceNone = CullFaceNone; + exports.Curve = Curve; + exports.CurvePath = CurvePath; + exports.CustomBlending = CustomBlending; + exports.CustomToneMapping = CustomToneMapping; + exports.CylinderBufferGeometry = CylinderBufferGeometry; + exports.CylinderGeometry = CylinderGeometry; + exports.Cylindrical = Cylindrical; + exports.DataTexture = DataTexture; + exports.DataTexture2DArray = DataTexture2DArray; + exports.DataTexture3D = DataTexture3D; + exports.DataTextureLoader = DataTextureLoader; + exports.DecrementStencilOp = DecrementStencilOp; + exports.DecrementWrapStencilOp = DecrementWrapStencilOp; + exports.DefaultLoadingManager = DefaultLoadingManager; + exports.DepthFormat = DepthFormat; + exports.DepthStencilFormat = DepthStencilFormat; + exports.DepthTexture = DepthTexture; + exports.DirectionalLight = DirectionalLight; + exports.DirectionalLightHelper = DirectionalLightHelper; + exports.DiscreteInterpolant = DiscreteInterpolant; + exports.DodecahedronBufferGeometry = DodecahedronBufferGeometry; + exports.DodecahedronGeometry = DodecahedronGeometry; + exports.DoubleSide = DoubleSide; + exports.DstAlphaFactor = DstAlphaFactor; + exports.DstColorFactor = DstColorFactor; + exports.DynamicBufferAttribute = DynamicBufferAttribute; + exports.DynamicCopyUsage = DynamicCopyUsage; + exports.DynamicDrawUsage = DynamicDrawUsage; + exports.DynamicReadUsage = DynamicReadUsage; + exports.EdgesGeometry = EdgesGeometry; + exports.EdgesHelper = EdgesHelper; + exports.EllipseCurve = EllipseCurve; + exports.EqualDepth = EqualDepth; + exports.EqualStencilFunc = EqualStencilFunc; + exports.EquirectangularReflectionMapping = EquirectangularReflectionMapping; + exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping; + exports.Euler = Euler; + exports.EventDispatcher = EventDispatcher; + exports.ExtrudeBufferGeometry = ExtrudeBufferGeometry; + exports.ExtrudeGeometry = ExtrudeGeometry; + exports.Face3 = Face3; + exports.Face4 = Face4; + exports.FaceColors = FaceColors; + exports.FileLoader = FileLoader; + exports.FlatShading = FlatShading; + exports.Float32Attribute = Float32Attribute; + exports.Float32BufferAttribute = Float32BufferAttribute; + exports.Float64Attribute = Float64Attribute; + exports.Float64BufferAttribute = Float64BufferAttribute; + exports.FloatType = FloatType; + exports.Fog = Fog; + exports.FogExp2 = FogExp2; + exports.Font = Font; + exports.FontLoader = FontLoader; + exports.FrontSide = FrontSide; + exports.Frustum = Frustum; + exports.GLBufferAttribute = GLBufferAttribute; + exports.GLSL1 = GLSL1; + exports.GLSL3 = GLSL3; + exports.GammaEncoding = GammaEncoding; + exports.Geometry = Geometry; + exports.GeometryUtils = GeometryUtils; + exports.GreaterDepth = GreaterDepth; + exports.GreaterEqualDepth = GreaterEqualDepth; + exports.GreaterEqualStencilFunc = GreaterEqualStencilFunc; + exports.GreaterStencilFunc = GreaterStencilFunc; + exports.GridHelper = GridHelper; + exports.Group = Group; + exports.HalfFloatType = HalfFloatType; + exports.HemisphereLight = HemisphereLight; + exports.HemisphereLightHelper = HemisphereLightHelper; + exports.HemisphereLightProbe = HemisphereLightProbe; + exports.IcosahedronBufferGeometry = IcosahedronBufferGeometry; + exports.IcosahedronGeometry = IcosahedronGeometry; + exports.ImageBitmapLoader = ImageBitmapLoader; + exports.ImageLoader = ImageLoader; + exports.ImageUtils = ImageUtils; + exports.ImmediateRenderObject = ImmediateRenderObject; + exports.IncrementStencilOp = IncrementStencilOp; + exports.IncrementWrapStencilOp = IncrementWrapStencilOp; + exports.InstancedBufferAttribute = InstancedBufferAttribute; + exports.InstancedBufferGeometry = InstancedBufferGeometry; + exports.InstancedInterleavedBuffer = InstancedInterleavedBuffer; + exports.InstancedMesh = InstancedMesh; + exports.Int16Attribute = Int16Attribute; + exports.Int16BufferAttribute = Int16BufferAttribute; + exports.Int32Attribute = Int32Attribute; + exports.Int32BufferAttribute = Int32BufferAttribute; + exports.Int8Attribute = Int8Attribute; + exports.Int8BufferAttribute = Int8BufferAttribute; + exports.IntType = IntType; + exports.InterleavedBuffer = InterleavedBuffer; + exports.InterleavedBufferAttribute = InterleavedBufferAttribute; + exports.Interpolant = Interpolant; + exports.InterpolateDiscrete = InterpolateDiscrete; + exports.InterpolateLinear = InterpolateLinear; + exports.InterpolateSmooth = InterpolateSmooth; + exports.InvertStencilOp = InvertStencilOp; + exports.JSONLoader = JSONLoader; + exports.KeepStencilOp = KeepStencilOp; + exports.KeyframeTrack = KeyframeTrack; + exports.LOD = LOD; + exports.LatheBufferGeometry = LatheBufferGeometry; + exports.LatheGeometry = LatheGeometry; + exports.Layers = Layers; + exports.LensFlare = LensFlare; + exports.LessDepth = LessDepth; + exports.LessEqualDepth = LessEqualDepth; + exports.LessEqualStencilFunc = LessEqualStencilFunc; + exports.LessStencilFunc = LessStencilFunc; + exports.Light = Light; + exports.LightProbe = LightProbe; + exports.Line = Line; + exports.Line3 = Line3; + exports.LineBasicMaterial = LineBasicMaterial; + exports.LineCurve = LineCurve; + exports.LineCurve3 = LineCurve3; + exports.LineDashedMaterial = LineDashedMaterial; + exports.LineLoop = LineLoop; + exports.LinePieces = LinePieces; + exports.LineSegments = LineSegments; + exports.LineStrip = LineStrip; + exports.LinearEncoding = LinearEncoding; + exports.LinearFilter = LinearFilter; + exports.LinearInterpolant = LinearInterpolant; + exports.LinearMipMapLinearFilter = LinearMipMapLinearFilter; + exports.LinearMipMapNearestFilter = LinearMipMapNearestFilter; + exports.LinearMipmapLinearFilter = LinearMipmapLinearFilter; + exports.LinearMipmapNearestFilter = LinearMipmapNearestFilter; + exports.LinearToneMapping = LinearToneMapping; + exports.Loader = Loader; + exports.LoaderUtils = LoaderUtils; + exports.LoadingManager = LoadingManager; + exports.LogLuvEncoding = LogLuvEncoding; + exports.LoopOnce = LoopOnce; + exports.LoopPingPong = LoopPingPong; + exports.LoopRepeat = LoopRepeat; + exports.LuminanceAlphaFormat = LuminanceAlphaFormat; + exports.LuminanceFormat = LuminanceFormat; + exports.MOUSE = MOUSE; + exports.Material = Material; + exports.MaterialLoader = MaterialLoader; + exports.Math = MathUtils; + exports.MathUtils = MathUtils; + exports.Matrix3 = Matrix3; + exports.Matrix4 = Matrix4; + exports.MaxEquation = MaxEquation; + exports.Mesh = Mesh; + exports.MeshBasicMaterial = MeshBasicMaterial; + exports.MeshDepthMaterial = MeshDepthMaterial; + exports.MeshDistanceMaterial = MeshDistanceMaterial; + exports.MeshFaceMaterial = MeshFaceMaterial; + exports.MeshLambertMaterial = MeshLambertMaterial; + exports.MeshMatcapMaterial = MeshMatcapMaterial; + exports.MeshNormalMaterial = MeshNormalMaterial; + exports.MeshPhongMaterial = MeshPhongMaterial; + exports.MeshPhysicalMaterial = MeshPhysicalMaterial; + exports.MeshStandardMaterial = MeshStandardMaterial; + exports.MeshToonMaterial = MeshToonMaterial; + exports.MinEquation = MinEquation; + exports.MirroredRepeatWrapping = MirroredRepeatWrapping; + exports.MixOperation = MixOperation; + exports.MultiMaterial = MultiMaterial; + exports.MultiplyBlending = MultiplyBlending; + exports.MultiplyOperation = MultiplyOperation; + exports.NearestFilter = NearestFilter; + exports.NearestMipMapLinearFilter = NearestMipMapLinearFilter; + exports.NearestMipMapNearestFilter = NearestMipMapNearestFilter; + exports.NearestMipmapLinearFilter = NearestMipmapLinearFilter; + exports.NearestMipmapNearestFilter = NearestMipmapNearestFilter; + exports.NeverDepth = NeverDepth; + exports.NeverStencilFunc = NeverStencilFunc; + exports.NoBlending = NoBlending; + exports.NoColors = NoColors; + exports.NoToneMapping = NoToneMapping; + exports.NormalAnimationBlendMode = NormalAnimationBlendMode; + exports.NormalBlending = NormalBlending; + exports.NotEqualDepth = NotEqualDepth; + exports.NotEqualStencilFunc = NotEqualStencilFunc; + exports.NumberKeyframeTrack = NumberKeyframeTrack; + exports.Object3D = Object3D; + exports.ObjectLoader = ObjectLoader; + exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap; + exports.OctahedronBufferGeometry = OctahedronBufferGeometry; + exports.OctahedronGeometry = OctahedronGeometry; + exports.OneFactor = OneFactor; + exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor; + exports.OneMinusDstColorFactor = OneMinusDstColorFactor; + exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor; + exports.OneMinusSrcColorFactor = OneMinusSrcColorFactor; + exports.OrthographicCamera = OrthographicCamera; + exports.PCFShadowMap = PCFShadowMap; + exports.PCFSoftShadowMap = PCFSoftShadowMap; + exports.PMREMGenerator = PMREMGenerator; + exports.ParametricBufferGeometry = ParametricBufferGeometry; + exports.ParametricGeometry = ParametricGeometry; + exports.Particle = Particle; + exports.ParticleBasicMaterial = ParticleBasicMaterial; + exports.ParticleSystem = ParticleSystem; + exports.ParticleSystemMaterial = ParticleSystemMaterial; + exports.Path = Path; + exports.PerspectiveCamera = PerspectiveCamera; + exports.Plane = Plane; + exports.PlaneBufferGeometry = PlaneBufferGeometry; + exports.PlaneGeometry = PlaneGeometry; + exports.PlaneHelper = PlaneHelper; + exports.PointCloud = PointCloud; + exports.PointCloudMaterial = PointCloudMaterial; + exports.PointLight = PointLight; + exports.PointLightHelper = PointLightHelper; + exports.Points = Points; + exports.PointsMaterial = PointsMaterial; + exports.PolarGridHelper = PolarGridHelper; + exports.PolyhedronBufferGeometry = PolyhedronBufferGeometry; + exports.PolyhedronGeometry = PolyhedronGeometry; + exports.PositionalAudio = PositionalAudio; + exports.PropertyBinding = PropertyBinding; + exports.PropertyMixer = PropertyMixer; + exports.QuadraticBezierCurve = QuadraticBezierCurve; + exports.QuadraticBezierCurve3 = QuadraticBezierCurve3; + exports.Quaternion = Quaternion; + exports.QuaternionKeyframeTrack = QuaternionKeyframeTrack; + exports.QuaternionLinearInterpolant = QuaternionLinearInterpolant; + exports.REVISION = REVISION; + exports.RGBADepthPacking = RGBADepthPacking; + exports.RGBAFormat = RGBAFormat; + exports.RGBAIntegerFormat = RGBAIntegerFormat; + exports.RGBA_ASTC_10x10_Format = RGBA_ASTC_10x10_Format; + exports.RGBA_ASTC_10x5_Format = RGBA_ASTC_10x5_Format; + exports.RGBA_ASTC_10x6_Format = RGBA_ASTC_10x6_Format; + exports.RGBA_ASTC_10x8_Format = RGBA_ASTC_10x8_Format; + exports.RGBA_ASTC_12x10_Format = RGBA_ASTC_12x10_Format; + exports.RGBA_ASTC_12x12_Format = RGBA_ASTC_12x12_Format; + exports.RGBA_ASTC_4x4_Format = RGBA_ASTC_4x4_Format; + exports.RGBA_ASTC_5x4_Format = RGBA_ASTC_5x4_Format; + exports.RGBA_ASTC_5x5_Format = RGBA_ASTC_5x5_Format; + exports.RGBA_ASTC_6x5_Format = RGBA_ASTC_6x5_Format; + exports.RGBA_ASTC_6x6_Format = RGBA_ASTC_6x6_Format; + exports.RGBA_ASTC_8x5_Format = RGBA_ASTC_8x5_Format; + exports.RGBA_ASTC_8x6_Format = RGBA_ASTC_8x6_Format; + exports.RGBA_ASTC_8x8_Format = RGBA_ASTC_8x8_Format; + exports.RGBA_BPTC_Format = RGBA_BPTC_Format; + exports.RGBA_ETC2_EAC_Format = RGBA_ETC2_EAC_Format; + exports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format; + exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format; + exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format; + exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format; + exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format; + exports.RGBDEncoding = RGBDEncoding; + exports.RGBEEncoding = RGBEEncoding; + exports.RGBEFormat = RGBEFormat; + exports.RGBFormat = RGBFormat; + exports.RGBIntegerFormat = RGBIntegerFormat; + exports.RGBM16Encoding = RGBM16Encoding; + exports.RGBM7Encoding = RGBM7Encoding; + exports.RGB_ETC1_Format = RGB_ETC1_Format; + exports.RGB_ETC2_Format = RGB_ETC2_Format; + exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format; + exports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format; + exports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format; + exports.RGFormat = RGFormat; + exports.RGIntegerFormat = RGIntegerFormat; + exports.RawShaderMaterial = RawShaderMaterial; + exports.Ray = Ray; + exports.Raycaster = Raycaster; + exports.RectAreaLight = RectAreaLight; + exports.RedFormat = RedFormat; + exports.RedIntegerFormat = RedIntegerFormat; + exports.ReinhardToneMapping = ReinhardToneMapping; + exports.RepeatWrapping = RepeatWrapping; + exports.ReplaceStencilOp = ReplaceStencilOp; + exports.ReverseSubtractEquation = ReverseSubtractEquation; + exports.RingBufferGeometry = RingBufferGeometry; + exports.RingGeometry = RingGeometry; + exports.SRGB8_ALPHA8_ASTC_10x10_Format = SRGB8_ALPHA8_ASTC_10x10_Format; + exports.SRGB8_ALPHA8_ASTC_10x5_Format = SRGB8_ALPHA8_ASTC_10x5_Format; + exports.SRGB8_ALPHA8_ASTC_10x6_Format = SRGB8_ALPHA8_ASTC_10x6_Format; + exports.SRGB8_ALPHA8_ASTC_10x8_Format = SRGB8_ALPHA8_ASTC_10x8_Format; + exports.SRGB8_ALPHA8_ASTC_12x10_Format = SRGB8_ALPHA8_ASTC_12x10_Format; + exports.SRGB8_ALPHA8_ASTC_12x12_Format = SRGB8_ALPHA8_ASTC_12x12_Format; + exports.SRGB8_ALPHA8_ASTC_4x4_Format = SRGB8_ALPHA8_ASTC_4x4_Format; + exports.SRGB8_ALPHA8_ASTC_5x4_Format = SRGB8_ALPHA8_ASTC_5x4_Format; + exports.SRGB8_ALPHA8_ASTC_5x5_Format = SRGB8_ALPHA8_ASTC_5x5_Format; + exports.SRGB8_ALPHA8_ASTC_6x5_Format = SRGB8_ALPHA8_ASTC_6x5_Format; + exports.SRGB8_ALPHA8_ASTC_6x6_Format = SRGB8_ALPHA8_ASTC_6x6_Format; + exports.SRGB8_ALPHA8_ASTC_8x5_Format = SRGB8_ALPHA8_ASTC_8x5_Format; + exports.SRGB8_ALPHA8_ASTC_8x6_Format = SRGB8_ALPHA8_ASTC_8x6_Format; + exports.SRGB8_ALPHA8_ASTC_8x8_Format = SRGB8_ALPHA8_ASTC_8x8_Format; + exports.Scene = Scene; + exports.SceneUtils = SceneUtils; + exports.ShaderChunk = ShaderChunk; + exports.ShaderLib = ShaderLib; + exports.ShaderMaterial = ShaderMaterial; + exports.ShadowMaterial = ShadowMaterial; + exports.Shape = Shape; + exports.ShapeBufferGeometry = ShapeBufferGeometry; + exports.ShapeGeometry = ShapeGeometry; + exports.ShapePath = ShapePath; + exports.ShapeUtils = ShapeUtils; + exports.ShortType = ShortType; + exports.Skeleton = Skeleton; + exports.SkeletonHelper = SkeletonHelper; + exports.SkinnedMesh = SkinnedMesh; + exports.SmoothShading = SmoothShading; + exports.Sphere = Sphere; + exports.SphereBufferGeometry = SphereBufferGeometry; + exports.SphereGeometry = SphereGeometry; + exports.Spherical = Spherical; + exports.SphericalHarmonics3 = SphericalHarmonics3; + exports.Spline = Spline; + exports.SplineCurve = SplineCurve; + exports.SplineCurve3 = SplineCurve3; + exports.SpotLight = SpotLight; + exports.SpotLightHelper = SpotLightHelper; + exports.Sprite = Sprite; + exports.SpriteMaterial = SpriteMaterial; + exports.SrcAlphaFactor = SrcAlphaFactor; + exports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor; + exports.SrcColorFactor = SrcColorFactor; + exports.StaticCopyUsage = StaticCopyUsage; + exports.StaticDrawUsage = StaticDrawUsage; + exports.StaticReadUsage = StaticReadUsage; + exports.StereoCamera = StereoCamera; + exports.StreamCopyUsage = StreamCopyUsage; + exports.StreamDrawUsage = StreamDrawUsage; + exports.StreamReadUsage = StreamReadUsage; + exports.StringKeyframeTrack = StringKeyframeTrack; + exports.SubtractEquation = SubtractEquation; + exports.SubtractiveBlending = SubtractiveBlending; + exports.TOUCH = TOUCH; + exports.TangentSpaceNormalMap = TangentSpaceNormalMap; + exports.TetrahedronBufferGeometry = TetrahedronBufferGeometry; + exports.TetrahedronGeometry = TetrahedronGeometry; + exports.TextBufferGeometry = TextBufferGeometry; + exports.TextGeometry = TextGeometry; + exports.Texture = Texture; + exports.TextureLoader = TextureLoader; + exports.TorusBufferGeometry = TorusBufferGeometry; + exports.TorusGeometry = TorusGeometry; + exports.TorusKnotBufferGeometry = TorusKnotBufferGeometry; + exports.TorusKnotGeometry = TorusKnotGeometry; + exports.Triangle = Triangle; + exports.TriangleFanDrawMode = TriangleFanDrawMode; + exports.TriangleStripDrawMode = TriangleStripDrawMode; + exports.TrianglesDrawMode = TrianglesDrawMode; + exports.TubeBufferGeometry = TubeBufferGeometry; + exports.TubeGeometry = TubeGeometry; + exports.UVMapping = UVMapping; + exports.Uint16Attribute = Uint16Attribute; + exports.Uint16BufferAttribute = Uint16BufferAttribute; + exports.Uint32Attribute = Uint32Attribute; + exports.Uint32BufferAttribute = Uint32BufferAttribute; + exports.Uint8Attribute = Uint8Attribute; + exports.Uint8BufferAttribute = Uint8BufferAttribute; + exports.Uint8ClampedAttribute = Uint8ClampedAttribute; + exports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute; + exports.Uniform = Uniform; + exports.UniformsLib = UniformsLib; + exports.UniformsUtils = UniformsUtils; + exports.UnsignedByteType = UnsignedByteType; + exports.UnsignedInt248Type = UnsignedInt248Type; + exports.UnsignedIntType = UnsignedIntType; + exports.UnsignedShort4444Type = UnsignedShort4444Type; + exports.UnsignedShort5551Type = UnsignedShort5551Type; + exports.UnsignedShort565Type = UnsignedShort565Type; + exports.UnsignedShortType = UnsignedShortType; + exports.VSMShadowMap = VSMShadowMap; + exports.Vector2 = Vector2; + exports.Vector3 = Vector3; + exports.Vector4 = Vector4; + exports.VectorKeyframeTrack = VectorKeyframeTrack; + exports.Vertex = Vertex; + exports.VertexColors = VertexColors; + exports.VideoTexture = VideoTexture; + exports.WebGL1Renderer = WebGL1Renderer; + exports.WebGLCubeRenderTarget = WebGLCubeRenderTarget; + exports.WebGLMultisampleRenderTarget = WebGLMultisampleRenderTarget; + exports.WebGLRenderTarget = WebGLRenderTarget; + exports.WebGLRenderTargetCube = WebGLRenderTargetCube; + exports.WebGLRenderer = WebGLRenderer; + exports.WebGLUtils = WebGLUtils; + exports.WireframeGeometry = WireframeGeometry; + exports.WireframeHelper = WireframeHelper; + exports.WrapAroundEnding = WrapAroundEnding; + exports.XHRLoader = XHRLoader; + exports.ZeroCurvatureEnding = ZeroCurvatureEnding; + exports.ZeroFactor = ZeroFactor; + exports.ZeroSlopeEnding = ZeroSlopeEnding; + exports.ZeroStencilOp = ZeroStencilOp; + exports.sRGBEncoding = sRGBEncoding; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/examples/loop.html b/examples/loop.html index 13492334..f076495a 100644 --- a/examples/loop.html +++ b/examples/loop.html @@ -3,7 +3,7 @@ Loop - Leap - + + + diff --git a/examples/plugins.html b/examples/plugins.html index 24556f5d..37ccd070 100644 --- a/examples/plugins.html +++ b/examples/plugins.html @@ -1,7 +1,7 @@ Plugins - Leap - + + + diff --git a/examples/threejs-bones.html b/examples/threejs-bones.html index 7c966342..8d7660e9 100644 --- a/examples/threejs-bones.html +++ b/examples/threejs-bones.html @@ -1,7 +1,7 @@ Bone Hands - Leap - + diff --git a/leap-1.0.0.min.js b/leap-1.0.0.min.js deleted file mode 100644 index c5c8847e..00000000 --- a/leap-1.0.0.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * LeapJS v1.0.0 - * http://github.com/leapmotion/leapjs/ - * - * Copyright 2013 LeapMotion, Inc. and other contributors - * Released under the Apache-2.0 license - * http://github.com/leapmotion/leapjs/blob/master/LICENSE - */ -!function o(a,s,u){function c(e,t){if(!s[e]){if(!a[e]){var n="function"==typeof require&&require;if(!t&&n)return n(e,!0);if(h)return h(e,!0);var r=new Error("Cannot find module '"+e+"'");throw r.code="MODULE_NOT_FOUND",r}var i=s[e]={exports:{}};a[e][0].call(i.exports,function(t){return c(a[e][1][t]||t)},i,i.exports,o,a,s,u)}return s[e].exports}for(var h="function"==typeof require&&require,t=0;t=this.size||t>=this._buf.length))return this._buf[(this.pos-t-1)%this.size]},r.prototype.push=function(t){return this._buf[this.pos%this.size]=t,this.pos++}},{}],3:[function(t,e,n){var r=t("../protocol").chooseProtocol,i=t("events").EventEmitter,o=t("underscore"),a=e.exports=function(t){this.opts=o.defaults(t||{},{host:"127.0.0.1",enableGestures:!1,scheme:this.getScheme(),port:this.getPort(),background:!1,optimizeHMD:!1,requestProtocolVersion:a.defaultProtocolVersion}),this.host=this.opts.host,this.port=this.opts.port,this.scheme=this.opts.scheme,this.protocolVersionVerified=!1,this.background=null,this.optimizeHMD=null,this.on("ready",function(){this.enableGestures(this.opts.enableGestures),this.setBackground(this.opts.background),this.setOptimizeHMD(this.opts.optimizeHMD),this.opts.optimizeHMD?console.log("Optimized for head mounted display usage."):console.log("Optimized for desktop usage.")})};a.defaultProtocolVersion=6,a.prototype.getUrl=function(){return this.scheme+"//"+this.host+":"+this.port+"/v"+this.opts.requestProtocolVersion+".json"},a.prototype.getScheme=function(){return"ws:"},a.prototype.getPort=function(){return 6437},a.prototype.setBackground=function(t){this.opts.background=t,this.protocol&&this.protocol.sendBackground&&this.background!==this.opts.background&&(this.background=this.opts.background,this.protocol.sendBackground(this,this.opts.background))},a.prototype.setOptimizeHMD=function(t){this.opts.optimizeHMD=t,this.protocol&&this.protocol.sendOptimizeHMD&&this.optimizeHMD!==this.opts.optimizeHMD&&(this.optimizeHMD=this.opts.optimizeHMD,this.protocol.sendOptimizeHMD(this,this.opts.optimizeHMD))},a.prototype.handleOpen=function(){this.connected||(this.connected=!0,this.emit("connect"))},a.prototype.enableGestures=function(t){this.gesturesEnabled=!!t,this.send(this.protocol.encode({enableGestures:this.gesturesEnabled}))},a.prototype.handleClose=function(t,e){this.connected&&(this.disconnect(),1001===t&&1Upgrade",{onclick:function(t){if("leapjs-decline-upgrade"!=t.target.id){var e=window.open(n,"_blank","height=800,width=1000,location=1,menubar=1,resizable=1,status=1,toolbar=1,scrollbars=1");window.focus&&e.focus()}return r.hide(),!0},onmousemove:function(t){t.target==document.getElementById("leapjs-decline-upgrade")?(document.getElementById("leapjs-decline-upgrade").style.color="#000",document.getElementById("leapjs-decline-upgrade").style.boxShadow="0px 0px 2px #5daa00",document.getElementById("leapjs-accept-upgrade").style.color="#444",document.getElementById("leapjs-accept-upgrade").style.boxShadow="none"):(document.getElementById("leapjs-accept-upgrade").style.color="#000",document.getElementById("leapjs-accept-upgrade").style.boxShadow="0px 0px 2px #5daa00",document.getElementById("leapjs-decline-upgrade").style.color="#444",document.getElementById("leapjs-decline-upgrade").style.boxShadow="none")},onmouseout:function(){document.getElementById("leapjs-decline-upgrade").style.color="#444",document.getElementById("leapjs-decline-upgrade").style.boxShadow="none",document.getElementById("leapjs-accept-upgrade").style.color="#444",document.getElementById("leapjs-accept-upgrade").style.boxShadow="none"}})).show()},i.hasWarnedBones=!1,i.warnBones=function(){this.hasWarnedBones||(this.hasWarnedBones=!0,console.warn("Your Leap Service is out of date"),void 0!==t&&t.versions&&t.versions.node||this.warnOutOfDate({reason:"bones"}))}}).call(this,t("_process"))},{_process:33}],8:[function(t,e,n){var r=t("./pointable"),i=t("./bone"),o=t("./dialog"),a=t("underscore"),s=e.exports=function(t){r.call(this,t),this.dipPosition=t.dipPosition,this.pipPosition=t.pipPosition,this.mcpPosition=t.mcpPosition,this.carpPosition=t.carpPosition,this.extended=t.extended,this.type=t.type,this.finger=!0,this.positions=[this.carpPosition,this.mcpPosition,this.pipPosition,this.dipPosition,this.tipPosition],t.bases?this.addBones(t):o.warnBones()};a.extend(s.prototype,r.prototype),s.prototype.addBones=function(t){this.metacarpal=new i(this,{type:0,width:this.width,prevJoint:this.carpPosition,nextJoint:this.mcpPosition,basis:t.bases[0]}),this.proximal=new i(this,{type:1,width:this.width,prevJoint:this.mcpPosition,nextJoint:this.pipPosition,basis:t.bases[1]}),this.medial=new i(this,{type:2,width:this.width,prevJoint:this.pipPosition,nextJoint:this.dipPosition,basis:t.bases[2]}),this.distal=new i(this,{type:3,width:this.width,prevJoint:this.dipPosition,nextJoint:t.btipPosition,basis:t.bases[3]}),this.bones=[this.metacarpal,this.proximal,this.medial,this.distal]},s.prototype.toString=function(){return"Finger [ id:"+this.id+" "+this.length+"mmx | width:"+this.width+"mm | direction:"+this.direction+" ]"},s.Invalid={valid:!1}},{"./bone":1,"./dialog":7,"./pointable":15,underscore:34}],9:[function(t,e,n){var u=t("./hand"),c=t("./pointable"),r=t("./gesture").createGesture,i=t("gl-matrix"),o=i.mat3,a=i.vec3,s=t("./interaction_box"),h=t("./finger"),l=t("underscore"),f=e.exports=function(t){if(this.valid=!0,this.id=t.id,this.timestamp=t.timestamp,this.hands=[],this.handsMap={},this.pointables=[],this.tools=[],this.fingers=[],t.interactionBox&&(this.interactionBox=new s(t.interactionBox)),this.gestures=[],this.pointablesMap={},this._translation=t.t,this._rotation=l.flatten(t.r),this._scaleFactor=t.s,this.data=t,this.type="frame",this.currentFrameRate=t.currentFrameRate,t.gestures)for(var e=0,n=t.gestures.length;e!=n;e++)this.gestures.push(r(t.gestures[e]));this.postprocessData(t)};f.prototype.postprocessData=function(t){for(var e=0,n=(t=t||this.data).hands.length;e!=n;e++){var r=new u(t.hands[e]);(r.frame=this).hands.push(r),this.handsMap[r.id]=r}t.pointables=l.sortBy(t.pointables,function(t){return t.id});for(var i=0,o=t.pointables.length;i!=o;i++){var a=t.pointables[i],s=a.dipPosition?new h(a):new c(a);(s.frame=this).addPointable(s)}},f.prototype.addPointable=function(t){if(this.pointables.push(t),((this.pointablesMap[t.id]=t).tool?this.tools:this.fingers).push(t),void 0!==t.handId&&this.handsMap.hasOwnProperty(t.handId)){var e=this.handsMap[t.handId];switch(e.pointables.push(t),(t.tool?e.tools:e.fingers).push(t),t.type){case 0:e.thumb=t;break;case 1:e.indexFinger=t;break;case 2:e.middleFinger=t;break;case 3:e.ringFinger=t;break;case 4:e.pinky=t}}},f.prototype.tool=function(t){var e=this.pointable(t);return e.tool?e:c.Invalid},f.prototype.pointable=function(t){return this.pointablesMap[t]||c.Invalid},f.prototype.finger=function(t){var e=this.pointable(t);return e.tool?c.Invalid:e},f.prototype.hand=function(t){return this.handsMap[t]||u.Invalid},f.prototype.rotationAngle=function(t,e){if(!this.valid||!t.valid)return 0;var n=this.rotationMatrix(t),r=.5*(n[0]+n[4]+n[8]-1),i=Math.acos(r);if(i=isNaN(i)?0:i,void 0!==e){var o=this.rotationAxis(t);i*=a.dot(o,a.normalize(a.create(),e))}return i},f.prototype.rotationAxis=function(t){return this.valid&&t.valid?a.normalize(a.create(),[this._rotation[7]-t._rotation[5],this._rotation[2]-t._rotation[6],this._rotation[3]-t._rotation[1]]):a.create()},f.prototype.rotationMatrix=function(t){if(!this.valid||!t.valid)return o.create();var e=o.transpose(o.create(),this._rotation);return o.multiply(o.create(),t._rotation,e)},f.prototype.scaleFactor=function(t){return this.valid&&t.valid?Math.exp(this._scaleFactor-t._scaleFactor):1},f.prototype.translation=function(t){return this.valid&&t.valid?a.subtract(a.create(),this._translation,t._translation):a.create()},f.prototype.toString=function(){var t="Frame [ id:"+this.id+" | timestamp:"+this.timestamp+" | Hand count:("+this.hands.length+") | Pointable count:("+this.pointables.length+")";return this.gestures&&(t+=" | Gesture count:("+this.gestures.length+")"),t+=" ]"},f.prototype.dump=function(){var t="";t+="Frame Info:
",t+=this.toString(),t+="

Hands:
";for(var e=0,n=this.hands.length;e!=n;e++)t+=" "+this.hands[e].toString()+"
";t+="

Pointables:
";for(var r=0,i=this.pointables.length;r!=i;r++)t+=" "+this.pointables[r].toString()+"
";if(this.gestures){t+="

Gestures:
";for(var o=0,a=this.gestures.length;o!=a;o++)t+=" "+this.gestures[o].toString()+"
"}return t+="

Raw JSON:
",t+=JSON.stringify(this.data)},f.Invalid={valid:!1,hands:[],fingers:[],tools:[],gestures:[],pointables:[],pointable:function(){return c.Invalid},finger:function(){return c.Invalid},hand:function(){return u.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return o.create()},rotationAxis:function(){return a.create()},scaleFactor:function(){return 1},translation:function(){return a.create()}}},{"./finger":8,"./gesture":10,"./hand":11,"./interaction_box":13,"./pointable":15,"gl-matrix":23,underscore:34}],10:[function(t,e,n){var r=t("gl-matrix").vec3,i=t("events").EventEmitter,a=t("underscore"),s=(n.createGesture=function(t){var e;switch(t.type){case"circle":e=new o(t);break;case"swipe":e=new u(t);break;case"screenTap":e=new c(t);break;case"keyTap":e=new h(t);break;default:throw"unknown gesture type"}return e.id=t.id,e.handIds=t.handIds.slice(),e.pointableIds=t.pointableIds.slice(),e.duration=t.duration,e.state=t.state,e.type=t.type,e},n.gestureListener=function(t,r){var i={},o={};t.on("gesture",function(t,e){if(t.type==r){if(("start"==t.state||"stop"==t.state)&&void 0===o[t.id]){var n=new s(t,e);o[t.id]=n,a.each(i,function(t,e){n.on(e,t)})}o[t.id].update(t,e),"stop"==t.state&&delete o[t.id]}});var e={start:function(t){return i.start=t,e},stop:function(t){return i.stop=t,e},complete:function(t){return i.stop=t,e},update:function(t){return i.update=t,e}};return e},n.Gesture=function(t,e){this.gestures=[t],this.frames=[e]});s.prototype.update=function(t,e){this.lastGesture=t,this.lastFrame=e,this.gestures.push(t),this.frames.push(e),this.emit(t.state,this)},s.prototype.translation=function(){return r.subtract(r.create(),this.lastGesture.startPosition,this.lastGesture.position)},a.extend(s.prototype,i.prototype);var o=function(t){this.center=t.center,this.normal=t.normal,this.progress=t.progress,this.radius=t.radius};o.prototype.toString=function(){return"CircleGesture ["+JSON.stringify(this)+"]"};var u=function(t){this.startPosition=t.startPosition,this.position=t.position,this.direction=t.direction,this.speed=t.speed};u.prototype.toString=function(){return"SwipeGesture ["+JSON.stringify(this)+"]"};var c=function(t){this.position=t.position,this.direction=t.direction,this.progress=t.progress};c.prototype.toString=function(){return"ScreenTapGesture ["+JSON.stringify(this)+"]"};var h=function(t){this.position=t.position,this.direction=t.direction,this.progress=t.progress};h.prototype.toString=function(){return"KeyTapGesture ["+JSON.stringify(this)+"]"}},{events:21,"gl-matrix":23,underscore:34}],11:[function(t,e,n){var r=t("./pointable"),i=t("./bone"),o=t("gl-matrix"),a=o.mat3,s=o.vec3,u=t("underscore"),c=e.exports=function(t){this.id=t.id,this.palmPosition=t.palmPosition,this.direction=t.direction,this.palmVelocity=t.palmVelocity,this.palmNormal=t.palmNormal,this.sphereCenter=t.sphereCenter,this.sphereRadius=t.sphereRadius,this.valid=!0,this.pointables=[],this.fingers=[],t.armBasis?this.arm=new i(this,{type:4,width:t.armWidth,prevJoint:t.elbow,nextJoint:t.wrist,basis:t.armBasis}):this.arm=null,this.tools=[],this._translation=t.t,this._rotation=u.flatten(t.r),this._scaleFactor=t.s,this.timeVisible=t.timeVisible,this.stabilizedPalmPosition=t.stabilizedPalmPosition,this.type=t.type,this.grabStrength=t.grabStrength,this.pinchStrength=t.pinchStrength,this.confidence=t.confidence};c.prototype.finger=function(t){var e=this.frame.finger(t);return e&&e.handId==this.id?e:r.Invalid},c.prototype.rotationAngle=function(t,e){if(!this.valid||!t.valid)return 0;if(!t.hand(this.id).valid)return 0;var n=this.rotationMatrix(t),r=.5*(n[0]+n[4]+n[8]-1),i=Math.acos(r);if(i=isNaN(i)?0:i,void 0!==e){var o=this.rotationAxis(t);i*=s.dot(o,s.normalize(s.create(),e))}return i},c.prototype.rotationAxis=function(t){if(!this.valid||!t.valid)return s.create();var e=t.hand(this.id);return e.valid?s.normalize(s.create(),[this._rotation[7]-e._rotation[5],this._rotation[2]-e._rotation[6],this._rotation[3]-e._rotation[1]]):s.create()},c.prototype.rotationMatrix=function(t){if(!this.valid||!t.valid)return a.create();var e=t.hand(this.id);if(!e.valid)return a.create();var n=a.transpose(a.create(),this._rotation);return a.multiply(a.create(),e._rotation,n)},c.prototype.scaleFactor=function(t){if(!this.valid||!t.valid)return 1;var e=t.hand(this.id);return e.valid?Math.exp(this._scaleFactor-e._scaleFactor):1},c.prototype.translation=function(t){if(!this.valid||!t.valid)return s.create();var e=t.hand(this.id);return e.valid?[this._translation[0]-e._translation[0],this._translation[1]-e._translation[1],this._translation[2]-e._translation[2]]:s.create()},c.prototype.toString=function(){return"Hand ("+this.type+") [ id: "+this.id+" | palm velocity:"+this.palmVelocity+" | sphere center:"+this.sphereCenter+" ] "},c.prototype.pitch=function(){return Math.atan2(this.direction[1],-this.direction[2])},c.prototype.yaw=function(){return Math.atan2(this.direction[0],-this.direction[2])},c.prototype.roll=function(){return Math.atan2(this.palmNormal[0],-this.palmNormal[1])},c.Invalid={valid:!1,fingers:[],tools:[],pointables:[],left:!1,pointable:function(){return r.Invalid},finger:function(){return r.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return a.create()},rotationAxis:function(){return s.create()},scaleFactor:function(){return 1},translation:function(){return s.create()}}},{"./bone":1,"./pointable":15,"gl-matrix":23,underscore:34}],12:[function(t,e,n){e.exports={Controller:t("./controller"),Frame:t("./frame"),Gesture:t("./gesture"),Hand:t("./hand"),Pointable:t("./pointable"),Finger:t("./finger"),InteractionBox:t("./interaction_box"),CircularBuffer:t("./circular_buffer"),UI:t("./ui"),JSONProtocol:t("./protocol").JSONProtocol,glMatrix:t("gl-matrix"),mat3:t("gl-matrix").mat3,vec3:t("gl-matrix").vec3,loopController:void 0,version:t("./version.js"),_:t("underscore"),EventEmitter:t("events").EventEmitter,loop:function(t,e){return t&&void 0===e&&"[object Function]"==={}.toString.call(t)&&(e=t,t={}),this.loopController?t&&this.loopController.setupFrameEvents(t):this.loopController=new this.Controller(t),this.loopController.loop(e),this.loopController},plugin:function(t,e){this.Controller.plugin(t,e)}}},{"./circular_buffer":2,"./controller":6,"./finger":8,"./frame":9,"./gesture":10,"./hand":11,"./interaction_box":13,"./pointable":15,"./protocol":16,"./ui":17,"./version.js":20,events:21,"gl-matrix":23,underscore:34}],13:[function(t,e,n){var r=t("gl-matrix").vec3,i=e.exports=function(t){this.valid=!0,this.center=t.center,this.size=t.size,this.width=t.size[0],this.height=t.size[1],this.depth=t.size[2]};i.prototype.denormalizePoint=function(t){return r.fromValues((t[0]-.5)*this.size[0]+this.center[0],(t[1]-.5)*this.size[1]+this.center[1],(t[2]-.5)*this.size[2]+this.center[2])},i.prototype.normalizePoint=function(t,e){var n=r.fromValues((t[0]-this.center[0])/this.size[0]+.5,(t[1]-this.center[1])/this.size[1]+.5,(t[2]-this.center[2])/this.size[2]+.5);return e&&(n[0]=Math.min(Math.max(n[0],0),1),n[1]=Math.min(Math.max(n[1],0),1),n[2]=Math.min(Math.max(n[2],0),1)),n},i.prototype.toString=function(){return"InteractionBox [ width:"+this.width+" | height:"+this.height+" | depth:"+this.depth+" ]"},i.Invalid={valid:!1}},{"gl-matrix":23}],14:[function(t,e,n){var r=e.exports=function(t){this.steps=[],this.controller=t};r.prototype.addStep=function(t){this.steps.push(t)},r.prototype.run=function(t){for(var e=this.steps.length,n=0;n!=e&&t;n++)t=this.steps[n](t);return t},r.prototype.removeStep=function(t){var e=this.steps.indexOf(t);if(-1===e)throw"Step not found in pipeline";this.steps.splice(e,1)},r.prototype.addWrappedStep=function(i,o){function t(t){var e,n,r;for(n=0,r=(e="frame"==i?[t]:t[i+"s"]||[]).length;n=this.start.x&&n.x<=this.end.x&&n.y>=this.start.y&&n.y<=this.end.y&&n.z>=this.start.z&&n.z<=this.end.z)return!0}return!1},o.prototype.listener=function(t){var e=this;return t&&t.nearThreshold&&this.setupNearRegion(t.nearThreshold),function(t){return e.updatePosition(t)}},o.prototype.clipper=function(){var e=this;return function(t){return e.updatePosition(t),e.enteredFrame?t:null}},o.prototype.setupNearRegion=function(t){var e=this.nearRegion=new o([this.start.x-t,this.start.y-t,this.start.z-t],[this.end.x+t,this.end.y+t,this.end.z+t]),n=this;e.on("enter",function(t){n.emit("near",t)}),e.on("exit",function(t){n.emit("far",t)}),n.on("exit",function(t){n.emit("near",t)})},o.prototype.updatePosition=function(t){return this.nearRegion&&this.nearRegion.updatePosition(t),this.hasPointables(t)&&null==this.enteredFrame?(this.enteredFrame=t,this.emit("enter",this.enteredFrame)):this.hasPointables(t)||null==this.enteredFrame||(this.enteredFrame=null,this.emit("exit",this.enteredFrame)),t},o.prototype.normalize=function(t){return new Vector([(t.x-this.start.x)/(this.end.x-this.start.x),(t.y-this.start.y)/(this.end.y-this.start.y),(t.z-this.start.z)/(this.end.z-this.start.z)])},o.prototype.mapToXY=function(t,e,n){var r=this.normalize(t),i=r.x,o=r.y;return 1i){a.warned=!0;var s=new Error("Possible EventEmitter memory leak detected. "+a.length+' "'+String(e)+'" listeners added. Use emitter.setMaxListeners() to increase limit.');s.name="MaxListenersExceededWarning",s.emitter=t,s.type=e,s.count=a.length,"object"==typeof console&&console.warn&&console.warn("%s: %s",s.name,s.message)}}else a=o[e]=n,++t._eventsCount;return t}function f(){if(!this.fired)switch(this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length){case 0:return this.listener.call(this.target);case 1:return this.listener.call(this.target,arguments[0]);case 2:return this.listener.call(this.target,arguments[0],arguments[1]);case 3:return this.listener.call(this.target,arguments[0],arguments[1],arguments[2]);default:for(var t=new Array(arguments.length),e=0;ey.EPSILON?(t[0]=e[0]/r,t[1]=e[1]/r,t[2]=e[2]/r):(t[0]=1,t[1]=0,t[2]=0);return n},n.getAngle=function(t,e){var n=x(t,e);return Math.acos(2*n*n-1)},n.multiply=c,n.rotateX=function(t,e,n){n*=.5;var r=e[0],i=e[1],o=e[2],a=e[3],s=Math.sin(n),u=Math.cos(n);return t[0]=r*u+a*s,t[1]=i*u+o*s,t[2]=o*u-i*s,t[3]=a*u-r*s,t},n.rotateY=function(t,e,n){n*=.5;var r=e[0],i=e[1],o=e[2],a=e[3],s=Math.sin(n),u=Math.cos(n);return t[0]=r*u-o*s,t[1]=i*u+a*s,t[2]=o*u+r*s,t[3]=a*u-i*s,t},n.rotateZ=function(t,e,n){n*=.5;var r=e[0],i=e[1],o=e[2],a=e[3],s=Math.sin(n),u=Math.cos(n);return t[0]=r*u+i*s,t[1]=i*u-r*s,t[2]=o*u+a*s,t[3]=a*u-o*s,t},n.calculateW=function(t,e){var n=e[0],r=e[1],i=e[2];return t[0]=n,t[1]=r,t[2]=i,t[3]=Math.sqrt(Math.abs(1-n*n-r*r-i*i)),t},n.exp=h,n.ln=l,n.pow=function(t,e,n){return l(t,e),w(t,t,n),h(t,t),t},n.slerp=f,n.random=function(t){var e=y.RANDOM(),n=y.RANDOM(),r=y.RANDOM(),i=Math.sqrt(1-e),o=Math.sqrt(e);return t[0]=i*Math.sin(2*Math.PI*n),t[1]=i*Math.cos(2*Math.PI*n),t[2]=o*Math.sin(2*Math.PI*r),t[3]=o*Math.cos(2*Math.PI*r),t},n.invert=function(t,e){var n=e[0],r=e[1],i=e[2],o=e[3],a=n*n+r*r+i*i+o*o,s=a?1/a:0;return t[0]=-n*s,t[1]=-r*s,t[2]=-i*s,t[3]=o*s,t},n.conjugate=function(t,e){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=e[3],t},n.fromMat3=p,n.fromEuler=function(t,e,n,r){var i=.5*Math.PI/180;e*=i,n*=i,r*=i;var o=Math.sin(e),a=Math.cos(e),s=Math.sin(n),u=Math.cos(n),c=Math.sin(r),h=Math.cos(r);return t[0]=o*u*h-a*s*c,t[1]=a*s*h+o*u*c,t[2]=a*u*c-o*s*h,t[3]=a*u*h+o*s*c,t},n.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},n.setAxes=n.sqlerp=n.rotationTo=n.equals=n.exactEquals=n.normalize=n.sqrLen=n.squaredLength=n.len=n.length=n.lerp=n.dot=n.scale=n.mul=n.add=n.set=n.copy=n.fromValues=n.clone=void 0;var y=a(t("./common.js")),r=a(t("./mat3.js")),i=a(t("./vec3.js")),o=a(t("./vec4.js"));function a(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){var r=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(t,n):{};r.get||r.set?Object.defineProperty(e,n,r):e[n]=t[n]}return e.default=t,e}function s(){var t=new y.ARRAY_TYPE(4);return y.ARRAY_TYPE!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t[3]=1,t}function u(t,e,n){n*=.5;var r=Math.sin(n);return t[0]=r*e[0],t[1]=r*e[1],t[2]=r*e[2],t[3]=Math.cos(n),t}function c(t,e,n){var r=e[0],i=e[1],o=e[2],a=e[3],s=n[0],u=n[1],c=n[2],h=n[3];return t[0]=r*h+a*s+i*c-o*u,t[1]=i*h+a*u+o*s-r*c,t[2]=o*h+a*c+r*u-i*s,t[3]=a*h-r*s-i*u-o*c,t}function h(t,e){var n=e[0],r=e[1],i=e[2],o=e[3],a=Math.sqrt(n*n+r*r+i*i),s=Math.exp(o),u=0y.EPSILON?(i=Math.acos(o),a=Math.sin(i),s=Math.sin((1-r)*i)/a,Math.sin(r*i)/a):(s=1-r,r),t[0]=s*c+u*p,t[1]=s*h+u*d,t[2]=s*l+u*v,t[3]=s*f+u*m,t}function p(t,e){var n,r=e[0]+e[4]+e[8];if(0e[0]&&(i=1),e[8]>e[3*i+i]&&(i=2);var o=(i+1)%3,a=(i+2)%3;n=Math.sqrt(e[3*i+i]-e[3*o+o]-e[3*a+a]+1),t[i]=.5*n,n=.5/n,t[3]=(e[3*o+a]-e[3*a+o])*n,t[o]=(e[3*o+i]+e[3*i+o])*n,t[a]=(e[3*a+i]+e[3*i+a])*n}return t}var d=o.clone;n.clone=d;var v=o.fromValues;n.fromValues=v;var m=o.copy;n.copy=m;var g=o.set;n.set=g;var b=o.add;n.add=b;var M=c;n.mul=M;var w=o.scale;n.scale=w;var x=o.dot;n.dot=x;var P=o.lerp;n.lerp=P;var O=o.length,_=n.length=O;n.len=_;var A=o.squaredLength,E=n.squaredLength=A;n.sqrLen=E;var j=o.normalize;n.normalize=j;var S=o.exactEquals;n.exactEquals=S;var L=o.equals;n.equals=L;var R,I,N,F=(R=i.create(),I=i.fromValues(1,0,0),N=i.fromValues(0,1,0),function(t,e,n){var r=i.dot(e,n);return r<-.999999?(i.cross(R,I,e),i.len(R)<1e-6&&i.cross(R,N,e),i.normalize(R,R),u(t,R,Math.PI),t):.999999":">",'"':""","'":"'","`":"`"},V=p.invert(C);p.escape=z(C),p.unescape=z(V),p.result=function(t,e,n){p.isArray(e)||(e=[e]);var r=e.length;if(!r)return p.isFunction(n)?n.call(t):n;for(var i=0;i/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};function H(t){return"\\"+G[t]}var J=/(.)^/,G={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},W=/\\|'|\r|\n|\u2028|\u2029/g;p.template=function(o,t,e){!t&&e&&(t=e),t=p.defaults({},t,p.templateSettings);var n,r=RegExp([(t.escape||J).source,(t.interpolate||J).source,(t.evaluate||J).source].join("|")+"|$","g"),a=0,s="__p+='";o.replace(r,function(t,e,n,r,i){return s+=o.slice(a,i).replace(W,H),a=i+t.length,e?s+="'+\n((__t=("+e+"))==null?'':_.escape(__t))+\n'":n?s+="'+\n((__t=("+n+"))==null?'':__t)+\n'":r&&(s+="';\n"+r+"\n__p+='"),t}),s+="';\n",t.variable||(s="with(obj||{}){\n"+s+"}\n"),s="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+s+"return __p;\n";try{n=new Function(t.variable||"obj","_",s)}catch(t){throw t.source=s,t}function i(t){return n.call(this,t,p)}var u=t.variable||"obj";return i.source="function("+u+"){\n"+s+"}",i},p.chain=function(t){var e=p(t);return e._chain=!0,e};function U(t,e){return t._chain?p(e).chain():e}p.mixin=function(n){return p.each(p.functions(n),function(t){var e=p[t]=n[t];p.prototype[t]=function(){var t=[this._wrapped];return i.apply(t,arguments),U(this,e.apply(p,t))}}),p},p.mixin(p),p.each(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var n=r[e];p.prototype[e]=function(){var t=this._wrapped;return n.apply(t,arguments),"shift"!==e&&"splice"!==e||0!==t.length||delete t[0],U(this,t)}}),p.each(["concat","join","slice"],function(t){var e=r[t];p.prototype[t]=function(){return U(this,e.apply(this._wrapped,arguments))}}),p.prototype.value=function(){return this._wrapped},p.prototype.valueOf=p.prototype.toJSON=p.prototype.value,p.prototype.toString=function(){return String(this._wrapped)},"function"==typeof define&&define.amd&&define("underscore",[],function(){return p})}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],35:[function(t,e,n){"use strict";e.exports=function(){throw new Error("ws does not work in the browser. Browser clients must use the native WebSocket object")}},{}],36:[function(t,e,n){"undefined"!=typeof window&&"function"!=typeof window.requestAnimationFrame&&(window.requestAnimationFrame=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){setTimeout(t,1e3/60)}),Leap=t("../lib/index")},{"../lib/index":12}]},{},[36]); \ No newline at end of file diff --git a/leap-1.0.0.js b/leap-1.1.0.js similarity index 72% rename from leap-1.0.0.js rename to leap-1.1.0.js index 2f6d943a..a5fe15a0 100644 --- a/leap-1.0.0.js +++ b/leap-1.1.0.js @@ -1,18 +1,17 @@ /*! - * LeapJS v1.0.0 + * LeapJS v1.1.0 * http://github.com/leapmotion/leapjs/ * - * Copyright 2013 LeapMotion, Inc. and other contributors + * Copyright 2020 Ultraleap, Inc. and other contributors * Released under the Apache-2.0 license * http://github.com/leapmotion/leapjs/blob/master/LICENSE */ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i b[key]) ? 1 : ((b[key] > a[key]) ? -1 : 0) }; + }; + + data.pointables.sort(sortBy("id")); for (var pointableIdx = 0, pointableCount = data.pointables.length; pointableIdx != pointableCount; pointableIdx++) { var pointableData = data.pointables[pointableIdx]; @@ -1737,18 +1682,18 @@ Frame.prototype.postprocessData = function(data){ /** * Adds data from a pointable element into the pointablesMap; * also adds the pointable to the frame.handsMap hand to which it belongs, - * and to the hand's tools or hand's fingers map. + * and to the hand's fingers map. * * @param pointable {Object} a Pointable */ Frame.prototype.addPointable = function (pointable) { this.pointables.push(pointable); this.pointablesMap[pointable.id] = pointable; - (pointable.tool ? this.tools : this.fingers).push(pointable); + (this.fingers).push(pointable); if (pointable.handId !== undefined && this.handsMap.hasOwnProperty(pointable.handId)) { var hand = this.handsMap[pointable.handId]; hand.pointables.push(pointable); - (pointable.tool ? hand.tools : hand.fingers).push(pointable); + (hand.fingers).push(pointable); switch (pointable.type){ case 0: hand.thumb = pointable; @@ -1769,43 +1714,18 @@ Frame.prototype.addPointable = function (pointable) { } }; -/** - * The tool with the specified ID in this frame. - * - * Use the Frame tool() function to retrieve a tool from - * this frame using an ID value obtained from a previous frame. - * This function always returns a Pointable object, but if no tool - * with the specified ID is present, an invalid Pointable object is returned. - * - * Note that ID values persist across frames, but only until tracking of a - * particular object is lost. If tracking of a tool is lost and subsequently - * regained, the new Pointable object representing that tool may have a - * different ID than that representing the tool in an earlier frame. - * - * @method tool - * @memberof Leap.Frame.prototype - * @param {String} id The ID value of a Tool object from a previous frame. - * @returns {Leap.Pointable} The tool with the - * matching ID if one exists in this frame; otherwise, an invalid Pointable object - * is returned. - */ -Frame.prototype.tool = function(id) { - var pointable = this.pointable(id); - return pointable.tool ? pointable : Pointable.Invalid; -}; - /** * The Pointable object with the specified ID in this frame. * * Use the Frame pointable() function to retrieve the Pointable object from * this frame using an ID value obtained from a previous frame. - * This function always returns a Pointable object, but if no finger or tool + * This function always returns a Pointable object, but if no finger * with the specified ID is present, an invalid Pointable object is returned. * * Note that ID values persist across frames, but only until tracking of a - * particular object is lost. If tracking of a finger or tool is lost and subsequently - * regained, the new Pointable object representing that finger or tool may have - * a different ID than that representing the finger or tool in an earlier frame. + * particular object is lost. If tracking of a finger is lost and subsequently + * regained, the new Pointable object representing that finger may have + * a different ID than that representing the finger in an earlier frame. * * @method pointable * @memberof Leap.Frame.prototype @@ -1839,8 +1759,7 @@ Frame.prototype.pointable = function(id) { * object is returned. */ Frame.prototype.finger = function(id) { - var pointable = this.pointable(id); - return !pointable.tool ? pointable : Pointable.Invalid; + return this.pointable(id); }; /** @@ -2007,13 +1926,12 @@ Frame.prototype.translation = function(sinceFrame) { */ Frame.prototype.toString = function() { var str = "Frame [ id:"+this.id+" | timestamp:"+this.timestamp+" | Hand count:("+this.hands.length+") | Pointable count:("+this.pointables.length+")"; - if (this.gestures) str += " | Gesture count:("+this.gestures.length+")"; str += " ]"; return str; } /** - * Returns a JSON-formatted string containing the hands, pointables and gestures + * Returns a JSON-formatted string containing the hands, pointables * in this frame. * * @method dump @@ -2032,12 +1950,6 @@ Frame.prototype.dump = function() { for (var pointableIdx = 0, pointableCount = this.pointables.length; pointableIdx != pointableCount; pointableIdx++) { out += " "+ this.pointables[pointableIdx].toString() + "
"; } - if (this.gestures) { - out += "

Gestures:
"; - for (var gestureIdx = 0, gestureCount = this.gestures.length; gestureIdx != gestureCount; gestureIdx++) { - out += " "+ this.gestures[gestureIdx].toString() + "
"; - } - } out += "

Raw JSON:
"; out += JSON.stringify(this.data); return out; @@ -2059,8 +1971,6 @@ Frame.Invalid = { valid: false, hands: [], fingers: [], - tools: [], - gestures: [], pointables: [], pointable: function() { return Pointable.Invalid }, finger: function() { return Pointable.Invalid }, @@ -2074,498 +1984,12 @@ Frame.Invalid = { translation: function() { return vec3.create(); } }; -},{"./finger":8,"./gesture":10,"./hand":11,"./interaction_box":13,"./pointable":15,"gl-matrix":23,"underscore":34}],10:[function(require,module,exports){ -var glMatrix = require("gl-matrix") - , vec3 = glMatrix.vec3 - , EventEmitter = require('events').EventEmitter - , _ = require('underscore'); - -/** - * Constructs a new Gesture object. - * - * An uninitialized Gesture object is considered invalid. Get valid instances - * of the Gesture class, which will be one of the Gesture subclasses, from a - * Frame object. - * - * @class Gesture - * @abstract - * @memberof Leap - * @classdesc - * The Gesture class represents a recognized movement by the user. - * - * The Leap watches the activity within its field of view for certain movement - * patterns typical of a user gesture or command. For example, a movement from side to - * side with the hand can indicate a swipe gesture, while a finger poking forward - * can indicate a screen tap gesture. - * - * When the Leap recognizes a gesture, it assigns an ID and adds a - * Gesture object to the frame gesture list. For continuous gestures, which - * occur over many frames, the Leap updates the gesture by adding - * a Gesture object having the same ID and updated properties in each - * subsequent frame. - * - * **Important:** Recognition for each type of gesture must be enabled; - * otherwise **no gestures are recognized or reported**. - * - * Subclasses of Gesture define the properties for the specific movement patterns - * recognized by the Leap. - * - * The Gesture subclasses for include: - * - * * CircleGesture -- A circular movement by a finger. - * * SwipeGesture -- A straight line movement by the hand with fingers extended. - * * ScreenTapGesture -- A forward tapping movement by a finger. - * * KeyTapGesture -- A downward tapping movement by a finger. - * - * Circle and swipe gestures are continuous and these objects can have a - * state of start, update, and stop. - * - * The screen tap gesture is a discrete gesture. The Leap only creates a single - * ScreenTapGesture object appears for each tap and it always has a stop state. - * - * Get valid Gesture instances from a Frame object. You can get a list of gestures - * from the Frame gestures array. You can also use the Frame gesture() method - * to find a gesture in the current frame using an ID value obtained in a - * previous frame. - * - * Gesture objects can be invalid. For example, when you get a gesture by ID - * using Frame.gesture(), and there is no gesture with that ID in the current - * frame, then gesture() returns an Invalid Gesture object (rather than a null - * value). Always check object validity in situations where a gesture might be - * invalid. - */ -var createGesture = exports.createGesture = function(data) { - var gesture; - switch (data.type) { - case 'circle': - gesture = new CircleGesture(data); - break; - case 'swipe': - gesture = new SwipeGesture(data); - break; - case 'screenTap': - gesture = new ScreenTapGesture(data); - break; - case 'keyTap': - gesture = new KeyTapGesture(data); - break; - default: - throw "unknown gesture type"; - } - - /** - * The gesture ID. - * - * All Gesture objects belonging to the same recognized movement share the - * same ID value. Use the ID value with the Frame::gesture() method to - * find updates related to this Gesture object in subsequent frames. - * - * @member id - * @memberof Leap.Gesture.prototype - * @type {number} - */ - gesture.id = data.id; - /** - * The list of hands associated with this Gesture, if any. - * - * If no hands are related to this gesture, the list is empty. - * - * @member handIds - * @memberof Leap.Gesture.prototype - * @type {Array} - */ - gesture.handIds = data.handIds.slice(); - /** - * The list of fingers and tools associated with this Gesture, if any. - * - * If no Pointable objects are related to this gesture, the list is empty. - * - * @member pointableIds - * @memberof Leap.Gesture.prototype - * @type {Array} - */ - gesture.pointableIds = data.pointableIds.slice(); - /** - * The elapsed duration of the recognized movement up to the - * frame containing this Gesture object, in microseconds. - * - * The duration reported for the first Gesture in the sequence (with the - * start state) will typically be a small positive number since - * the movement must progress far enough for the Leap to recognize it as - * an intentional gesture. - * - * @member duration - * @memberof Leap.Gesture.prototype - * @type {number} - */ - gesture.duration = data.duration; - /** - * The gesture ID. - * - * Recognized movements occur over time and have a beginning, a middle, - * and an end. The 'state()' attribute reports where in that sequence this - * Gesture object falls. - * - * Possible values for the state field are: - * - * * start - * * update - * * stop - * - * @member state - * @memberof Leap.Gesture.prototype - * @type {String} - */ - gesture.state = data.state; - /** - * The gesture type. - * - * Possible values for the type field are: - * - * * circle - * * swipe - * * screenTap - * * keyTap - * - * @member type - * @memberof Leap.Gesture.prototype - * @type {String} - */ - gesture.type = data.type; - return gesture; -} - -/* - * Returns a builder object, which uses method chaining for gesture callback binding. - */ -var gestureListener = exports.gestureListener = function(controller, type) { - var handlers = {}; - var gestureMap = {}; - - controller.on('gesture', function(gesture, frame) { - if (gesture.type == type) { - if (gesture.state == "start" || gesture.state == "stop") { - if (gestureMap[gesture.id] === undefined) { - var gestureTracker = new Gesture(gesture, frame); - gestureMap[gesture.id] = gestureTracker; - _.each(handlers, function(cb, name) { - gestureTracker.on(name, cb); - }); - } - } - gestureMap[gesture.id].update(gesture, frame); - if (gesture.state == "stop") { - delete gestureMap[gesture.id]; - } - } - }); - var builder = { - start: function(cb) { - handlers['start'] = cb; - return builder; - }, - stop: function(cb) { - handlers['stop'] = cb; - return builder; - }, - complete: function(cb) { - handlers['stop'] = cb; - return builder; - }, - update: function(cb) { - handlers['update'] = cb; - return builder; - } - } - return builder; -} - -var Gesture = exports.Gesture = function(gesture, frame) { - this.gestures = [gesture]; - this.frames = [frame]; -} - -Gesture.prototype.update = function(gesture, frame) { - this.lastGesture = gesture; - this.lastFrame = frame; - this.gestures.push(gesture); - this.frames.push(frame); - this.emit(gesture.state, this); -} - -Gesture.prototype.translation = function() { - return vec3.subtract(vec3.create(), this.lastGesture.startPosition, this.lastGesture.position); -} - -_.extend(Gesture.prototype, EventEmitter.prototype); - -/** - * Constructs a new CircleGesture object. - * - * An uninitialized CircleGesture object is considered invalid. Get valid instances - * of the CircleGesture class from a Frame object. - * - * @class CircleGesture - * @memberof Leap - * @augments Leap.Gesture - * @classdesc - * The CircleGesture classes represents a circular finger movement. - * - * A circle movement is recognized when the tip of a finger draws a circle - * within the Leap field of view. - * - * ![CircleGesture](images/Leap_Gesture_Circle.png) - * - * Circle gestures are continuous. The CircleGesture objects for the gesture have - * three possible states: - * - * * start -- The circle gesture has just started. The movement has - * progressed far enough for the recognizer to classify it as a circle. - * * update -- The circle gesture is continuing. - * * stop -- The circle gesture is finished. - */ -var CircleGesture = function(data) { - /** - * The center point of the circle within the Leap frame of reference. - * - * @member center - * @memberof Leap.CircleGesture.prototype - * @type {number[]} - */ - this.center = data.center; - /** - * The normal vector for the circle being traced. - * - * If you draw the circle clockwise, the normal vector points in the same - * general direction as the pointable object drawing the circle. If you draw - * the circle counterclockwise, the normal points back toward the - * pointable. If the angle between the normal and the pointable object - * drawing the circle is less than 90 degrees, then the circle is clockwise. - * - * ```javascript - * var clockwiseness; - * if (circle.pointable.direction.angleTo(circle.normal) <= PI/4) { - * clockwiseness = "clockwise"; - * } - * else - * { - * clockwiseness = "counterclockwise"; - * } - * ``` - * - * @member normal - * @memberof Leap.CircleGesture.prototype - * @type {number[]} - */ - this.normal = data.normal; - /** - * The number of times the finger tip has traversed the circle. - * - * Progress is reported as a positive number of the number. For example, - * a progress value of .5 indicates that the finger has gone halfway - * around, while a value of 3 indicates that the finger has gone around - * the the circle three times. - * - * Progress starts where the circle gesture began. Since the circle - * must be partially formed before the Leap can recognize it, progress - * will be greater than zero when a circle gesture first appears in the - * frame. - * - * @member progress - * @memberof Leap.CircleGesture.prototype - * @type {number} - */ - this.progress = data.progress; - /** - * The radius of the circle in mm. - * - * @member radius - * @memberof Leap.CircleGesture.prototype - * @type {number} - */ - this.radius = data.radius; -} - -CircleGesture.prototype.toString = function() { - return "CircleGesture ["+JSON.stringify(this)+"]"; -} - -/** - * Constructs a new SwipeGesture object. - * - * An uninitialized SwipeGesture object is considered invalid. Get valid instances - * of the SwipeGesture class from a Frame object. - * - * @class SwipeGesture - * @memberof Leap - * @augments Leap.Gesture - * @classdesc - * The SwipeGesture class represents a swiping motion of a finger or tool. - * - * ![SwipeGesture](images/Leap_Gesture_Swipe.png) - * - * Swipe gestures are continuous. - */ -var SwipeGesture = function(data) { - /** - * The starting position within the Leap frame of - * reference, in mm. - * - * @member startPosition - * @memberof Leap.SwipeGesture.prototype - * @type {number[]} - */ - this.startPosition = data.startPosition; - /** - * The current swipe position within the Leap frame of - * reference, in mm. - * - * @member position - * @memberof Leap.SwipeGesture.prototype - * @type {number[]} - */ - this.position = data.position; - /** - * The unit direction vector parallel to the swipe motion. - * - * You can compare the components of the vector to classify the swipe as - * appropriate for your application. For example, if you are using swipes - * for two dimensional scrolling, you can compare the x and y values to - * determine if the swipe is primarily horizontal or vertical. - * - * @member direction - * @memberof Leap.SwipeGesture.prototype - * @type {number[]} - */ - this.direction = data.direction; - /** - * The speed of the finger performing the swipe gesture in - * millimeters per second. - * - * @member speed - * @memberof Leap.SwipeGesture.prototype - * @type {number} - */ - this.speed = data.speed; -} - -SwipeGesture.prototype.toString = function() { - return "SwipeGesture ["+JSON.stringify(this)+"]"; -} - -/** - * Constructs a new ScreenTapGesture object. - * - * An uninitialized ScreenTapGesture object is considered invalid. Get valid instances - * of the ScreenTapGesture class from a Frame object. - * - * @class ScreenTapGesture - * @memberof Leap - * @augments Leap.Gesture - * @classdesc - * The ScreenTapGesture class represents a tapping gesture by a finger or tool. - * - * A screen tap gesture is recognized when the tip of a finger pokes forward - * and then springs back to approximately the original postion, as if - * tapping a vertical screen. The tapping finger must pause briefly before beginning the tap. - * - * ![ScreenTap](images/Leap_Gesture_Tap2.png) - * - * ScreenTap gestures are discrete. The ScreenTapGesture object representing a tap always - * has the state, STATE_STOP. Only one ScreenTapGesture object is created for each - * screen tap gesture recognized. - */ -var ScreenTapGesture = function(data) { - /** - * The position where the screen tap is registered. - * - * @member position - * @memberof Leap.ScreenTapGesture.prototype - * @type {number[]} - */ - this.position = data.position; - /** - * The direction of finger tip motion. - * - * @member direction - * @memberof Leap.ScreenTapGesture.prototype - * @type {number[]} - */ - this.direction = data.direction; - /** - * The progess value is always 1.0 for a screen tap gesture. - * - * @member progress - * @memberof Leap.ScreenTapGesture.prototype - * @type {number} - */ - this.progress = data.progress; -} - -ScreenTapGesture.prototype.toString = function() { - return "ScreenTapGesture ["+JSON.stringify(this)+"]"; -} - -/** - * Constructs a new KeyTapGesture object. - * - * An uninitialized KeyTapGesture object is considered invalid. Get valid instances - * of the KeyTapGesture class from a Frame object. - * - * @class KeyTapGesture - * @memberof Leap - * @augments Leap.Gesture - * @classdesc - * The KeyTapGesture class represents a tapping gesture by a finger or tool. - * - * A key tap gesture is recognized when the tip of a finger rotates down toward the - * palm and then springs back to approximately the original postion, as if - * tapping. The tapping finger must pause briefly before beginning the tap. - * - * ![KeyTap](images/Leap_Gesture_Tap.png) - * - * Key tap gestures are discrete. The KeyTapGesture object representing a tap always - * has the state, STATE_STOP. Only one KeyTapGesture object is created for each - * key tap gesture recognized. - */ -var KeyTapGesture = function(data) { - /** - * The position where the key tap is registered. - * - * @member position - * @memberof Leap.KeyTapGesture.prototype - * @type {number[]} - */ - this.position = data.position; - /** - * The direction of finger tip motion. - * - * @member direction - * @memberof Leap.KeyTapGesture.prototype - * @type {number[]} - */ - this.direction = data.direction; - /** - * The progess value is always 1.0 for a key tap gesture. - * - * @member progress - * @memberof Leap.KeyTapGesture.prototype - * @type {number} - */ - this.progress = data.progress; -} - -KeyTapGesture.prototype.toString = function() { - return "KeyTapGesture ["+JSON.stringify(this)+"]"; -} - -},{"events":21,"gl-matrix":23,"underscore":34}],11:[function(require,module,exports){ +},{"./finger":8,"./hand":10,"./interaction_box":12,"./pointable":14,"gl-matrix":22}],10:[function(require,module,exports){ var Pointable = require("./pointable") , Bone = require('./bone') , glMatrix = require("gl-matrix") , mat3 = glMatrix.mat3 - , vec3 = glMatrix.vec3 - , _ = require("underscore"); + , vec3 = glMatrix.vec3; /** * Constructs a Hand object. @@ -2579,7 +2003,7 @@ var Pointable = require("./pointable") * * Hand tracking data includes a palm position and velocity; vectors for * the palm normal and direction to the fingers; properties of a sphere fit - * to the hand; and lists of the attached fingers and tools. + * to the hand; and lists of the attached fingers. * * Note that Hand objects can be invalid, which means that they do not contain * valid tracking data and do not correspond to a physical entity. Invalid Hand @@ -2674,14 +2098,13 @@ var Hand = module.exports = function(data) { */ this.valid = true; /** - * The list of Pointable objects (fingers and tools) detected in this frame + * The list of Pointable objects (fingers) detected in this frame * that are associated with this hand, given in arbitrary order. The list * can be empty if no fingers or tools associated with this hand are detected. * * Use the {@link Pointable} tool property to determine * whether or not an item in the list represents a tool or finger. - * You can also get only the tools using the Hand.tools[] list or - * only the fingers using the Hand.fingers[] list. + * You can also get only the fingers using the Hand.fingers[] list. * * @member pointables[] * @memberof Leap.Hand.prototype @@ -2712,19 +2135,13 @@ var Hand = module.exports = function(data) { this.arm = null; } - /** - * The list of tools detected in this frame that are held by this - * hand, given in arbitrary order. - * - * The list can be empty if no tools held by this hand are detected. - * - * @member tools[] - * @memberof Leap.Hand.prototype - * @type {Leap.Pointable[]} - */ - this.tools = []; this._translation = data.t; - this._rotation = _.flatten(data.r); + function flattenDeep(arr) { + return Array.isArray(arr) + ? arr.reduce(function (a, b) { return a.concat(flattenDeep(b)) }, []) + : [arr]; + } + this._rotation = flattenDeep(data.r); this._scaleFactor = data.s; /** @@ -2785,7 +2202,7 @@ Hand.prototype.finger = function(id) { /** * The angle of rotation around the rotation axis derived from the change in - * orientation of this hand, and any associated fingers and tools, between the + * orientation of this hand, and any associated fingers, between the * current frame and the specified frame. * * The returned angle is expressed in radians measured clockwise around the @@ -2820,7 +2237,7 @@ Hand.prototype.rotationAngle = function(sinceFrame, axis) { /** * The axis of rotation derived from the change in orientation of this hand, and - * any associated fingers and tools, between the current frame and the specified frame. + * any associated fingers, between the current frame and the specified frame. * * The returned direction vector is normalized. * @@ -2846,7 +2263,7 @@ Hand.prototype.rotationAxis = function(sinceFrame) { /** * The transform matrix expressing the rotation derived from the change in - * orientation of this hand, and any associated fingers and tools, between + * orientation of this hand, and any associated fingers, between * the current frame and the specified frame. * * If a corresponding Hand object is not found in sinceFrame, or if either @@ -2875,7 +2292,7 @@ Hand.prototype.rotationMatrix = function(sinceFrame) { * Values between 0.0 and 1.0 indicate contraction and values greater than 1.0 indicate expansion. * * The Leap derives scaling from the relative inward or outward motion of a hand - * and its associated fingers and tools (independent of translation and rotation). + * and its associated fingers (independent of translation and rotation). * * If a corresponding Hand object is not found in sinceFrame, or if either this frame or sinceFrame * are invalid Frame objects, then this method returns 1.0. @@ -2999,7 +2416,6 @@ Hand.prototype.roll = function() { Hand.Invalid = { valid: false, fingers: [], - tools: [], pointables: [], left: false, pointable: function() { return Pointable.Invalid }, @@ -3013,7 +2429,7 @@ Hand.Invalid = { translation: function() { return vec3.create(); } }; -},{"./bone":1,"./pointable":15,"gl-matrix":23,"underscore":34}],12:[function(require,module,exports){ +},{"./bone":1,"./pointable":14,"gl-matrix":22}],11:[function(require,module,exports){ /** * Leap is the global namespace of the Leap API. * @namespace Leap @@ -3021,7 +2437,6 @@ Hand.Invalid = { module.exports = { Controller: require("./controller"), Frame: require("./frame"), - Gesture: require("./gesture"), Hand: require("./hand"), Pointable: require("./pointable"), Finger: require("./finger"), @@ -3038,9 +2453,7 @@ module.exports = { /** * Expose utility libraries for convenience * Use carefully - they may be subject to upgrade or removal in different versions of LeapJS. - * */ - _: require('underscore'), EventEmitter: require('events').EventEmitter, /** @@ -3100,7 +2513,7 @@ module.exports = { } } -},{"./circular_buffer":2,"./controller":6,"./finger":8,"./frame":9,"./gesture":10,"./hand":11,"./interaction_box":13,"./pointable":15,"./protocol":16,"./ui":17,"./version.js":20,"events":21,"gl-matrix":23,"underscore":34}],13:[function(require,module,exports){ +},{"./circular_buffer":2,"./controller":6,"./finger":8,"./frame":9,"./hand":10,"./interaction_box":12,"./pointable":14,"./protocol":15,"./ui":16,"./version.js":19,"events":20,"gl-matrix":22}],12:[function(require,module,exports){ var glMatrix = require("gl-matrix") , vec3 = glMatrix.vec3; @@ -3242,7 +2655,7 @@ InteractionBox.prototype.toString = function() { */ InteractionBox.Invalid = { valid: false }; -},{"gl-matrix":23}],14:[function(require,module,exports){ +},{"gl-matrix":22}],13:[function(require,module,exports){ var Pipeline = module.exports = function (controller) { this.steps = []; this.controller = controller; @@ -3276,7 +2689,7 @@ Pipeline.prototype.removeStep = function(step){ * @memberOf Leap.Controller.prototype * @param {Controller} The controller on which the callback is called. * @param {String} type What frame object the callback is run for and receives. - * Can be one of 'frame', 'finger', 'hand', 'pointable', 'tool' + * Can be one of 'frame', 'finger', 'hand', 'pointable' * @param {function} callback The method which will be run inside the pipeline loop. Receives one argument, such as a hand. * @private */ @@ -3296,7 +2709,7 @@ Pipeline.prototype.addWrappedStep = function (type, callback) { this.addStep(step); return step; }; -},{}],15:[function(require,module,exports){ +},{}],14:[function(require,module,exports){ var glMatrix = require("gl-matrix") , vec3 = glMatrix.vec3; @@ -3513,12 +2926,8 @@ Pointable.prototype.hand = function(){ */ Pointable.Invalid = { valid: false }; -},{"gl-matrix":23}],16:[function(require,module,exports){ +},{"gl-matrix":22}],15:[function(require,module,exports){ var Frame = require('./frame') - , Hand = require('./hand') - , Pointable = require('./pointable') - , Finger = require('./finger') - , _ = require('underscore') , EventEmitter = require('events').EventEmitter; var Event = function(data) { @@ -3582,19 +2991,19 @@ var JSONProtocol = exports.JSONProtocol = function(header) { protocol.versionLong = 'Version ' + header.version; protocol.type = 'protocol'; - _.extend(protocol, EventEmitter.prototype); + Object.assign(protocol, EventEmitter.prototype); return protocol; }; -},{"./finger":8,"./frame":9,"./hand":11,"./pointable":15,"events":21,"underscore":34}],17:[function(require,module,exports){ +},{"./frame":9,"events":20}],16:[function(require,module,exports){ exports.UI = { Region: require("./ui/region"), Cursor: require("./ui/cursor") }; -},{"./ui/cursor":18,"./ui/region":19}],18:[function(require,module,exports){ +},{"./ui/cursor":17,"./ui/region":18}],17:[function(require,module,exports){ var Cursor = module.exports = function() { return function(frame) { var pointable = frame.pointables.sort(function(a, b) { return a.z - b.z })[0] @@ -3605,9 +3014,8 @@ var Cursor = module.exports = function() { } } -},{}],19:[function(require,module,exports){ -var EventEmitter = require('events').EventEmitter - , _ = require('underscore') +},{}],18:[function(require,module,exports){ +var EventEmitter = require('events').EventEmitter; var Region = module.exports = function(start, end) { this.start = new Vector(start) @@ -3692,16 +3100,16 @@ Region.prototype.mapToXY = function(position, width, height) { ] } -_.extend(Region.prototype, EventEmitter.prototype) -},{"events":21,"underscore":34}],20:[function(require,module,exports){ +Object.assign(Region.prototype, EventEmitter.prototype) +},{"events":20}],19:[function(require,module,exports){ // This file is automatically updated from package.json by grunt. module.exports = { - full: '1.0.0', + full: '1.1.0', major: 1, - minor: 0, + minor: 1, dot: 0 } -},{}],21:[function(require,module,exports){ +},{}],20:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -4226,7 +3634,7 @@ function functionBindPolyfill(context) { }; } -},{}],22:[function(require,module,exports){ +},{}],21:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -4250,7 +3658,7 @@ var RANDOM = Math.random; /** * Sets the type of array used when creating new vectors and matrices * - * @param {Type} type Array type, such as Float32Array or Array + * @param {Float32ArrayConstructor | ArrayConstructor} type Array type, such as Float32Array or Array */ exports.RANDOM = RANDOM; @@ -4294,9 +3702,11 @@ if (!Math.hypot) Math.hypot = function () { return Math.sqrt(y); }; -},{}],23:[function(require,module,exports){ +},{}],22:[function(require,module,exports){ "use strict"; +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + Object.defineProperty(exports, "__esModule", { value: true }); @@ -4342,10 +3752,14 @@ var vec4 = _interopRequireWildcard(require("./vec4.js")); exports.vec4 = vec4; -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } } -},{"./common.js":22,"./mat2.js":24,"./mat2d.js":25,"./mat3.js":26,"./mat4.js":27,"./quat.js":28,"./quat2.js":29,"./vec2.js":30,"./vec3.js":31,"./vec4.js":32}],24:[function(require,module,exports){ +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } +},{"./common.js":21,"./mat2.js":23,"./mat2d.js":24,"./mat3.js":25,"./mat4.js":26,"./quat.js":27,"./quat2.js":28,"./vec2.js":29,"./vec3.js":30,"./vec4.js":31}],23:[function(require,module,exports){ "use strict"; +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + Object.defineProperty(exports, "__esModule", { value: true }); @@ -4377,7 +3791,9 @@ exports.sub = exports.mul = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } } +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 2x2 Matrix @@ -4404,7 +3820,7 @@ function create() { /** * Creates a new mat2 initialized with values from an existing matrix * - * @param {mat2} a matrix to clone + * @param {ReadonlyMat2} a matrix to clone * @returns {mat2} a new 2x2 matrix */ @@ -4421,7 +3837,7 @@ function clone(a) { * Copy the values from one mat2 to another * * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix + * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ @@ -4490,7 +3906,7 @@ function set(out, m00, m01, m10, m11) { * Transpose the values of a mat2 * * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix + * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ @@ -4515,7 +3931,7 @@ function transpose(out, a) { * Inverts a mat2 * * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix + * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ @@ -4543,7 +3959,7 @@ function invert(out, a) { * Calculates the adjugate of a mat2 * * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix + * @param {ReadonlyMat2} a the source matrix * @returns {mat2} out */ @@ -4560,7 +3976,7 @@ function adjoint(out, a) { /** * Calculates the determinant of a mat2 * - * @param {mat2} a the source matrix + * @param {ReadonlyMat2} a the source matrix * @returns {Number} determinant of a */ @@ -4572,8 +3988,8 @@ function determinant(a) { * Multiplies two mat2's * * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand * @returns {mat2} out */ @@ -4597,7 +4013,7 @@ function multiply(out, a, b) { * Rotates a mat2 by the given angle * * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to rotate + * @param {ReadonlyMat2} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat2} out */ @@ -4620,8 +4036,8 @@ function rotate(out, a, rad) { * Scales the mat2 by the dimensions in the given vec2 * * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to rotate - * @param {vec2} v the vec2 to scale the matrix by + * @param {ReadonlyMat2} a the matrix to rotate + * @param {ReadonlyVec2} v the vec2 to scale the matrix by * @returns {mat2} out **/ @@ -4669,7 +4085,7 @@ function fromRotation(out, rad) { * mat2.scale(dest, dest, vec); * * @param {mat2} out mat2 receiving operation result - * @param {vec2} v Scaling vector + * @param {ReadonlyVec2} v Scaling vector * @returns {mat2} out */ @@ -4684,18 +4100,18 @@ function fromScaling(out, v) { /** * Returns a string representation of a mat2 * - * @param {mat2} a matrix to represent as a string + * @param {ReadonlyMat2} a matrix to represent as a string * @returns {String} string representation of the matrix */ function str(a) { - return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; + return "mat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; } /** * Returns Frobenius norm of a mat2 * - * @param {mat2} a the matrix to calculate Frobenius norm of + * @param {ReadonlyMat2} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ @@ -4705,10 +4121,10 @@ function frob(a) { } /** * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix - * @param {mat2} L the lower triangular matrix - * @param {mat2} D the diagonal matrix - * @param {mat2} U the upper triangular matrix - * @param {mat2} a the input matrix to factorize + * @param {ReadonlyMat2} L the lower triangular matrix + * @param {ReadonlyMat2} D the diagonal matrix + * @param {ReadonlyMat2} U the upper triangular matrix + * @param {ReadonlyMat2} a the input matrix to factorize */ @@ -4723,8 +4139,8 @@ function LDU(L, D, U, a) { * Adds two mat2's * * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand * @returns {mat2} out */ @@ -4740,8 +4156,8 @@ function add(out, a, b) { * Subtracts matrix b from matrix a * * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand * @returns {mat2} out */ @@ -4756,8 +4172,8 @@ function subtract(out, a, b) { /** * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) * - * @param {mat2} a The first matrix. - * @param {mat2} b The second matrix. + * @param {ReadonlyMat2} a The first matrix. + * @param {ReadonlyMat2} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ @@ -4768,8 +4184,8 @@ function exactEquals(a, b) { /** * Returns whether or not the matrices have approximately the same elements in the same position. * - * @param {mat2} a The first matrix. - * @param {mat2} b The second matrix. + * @param {ReadonlyMat2} a The first matrix. + * @param {ReadonlyMat2} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ @@ -4789,7 +4205,7 @@ function equals(a, b) { * Multiply each element of the matrix by a scalar. * * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to scale + * @param {ReadonlyMat2} a the matrix to scale * @param {Number} b amount to scale the matrix's elements by * @returns {mat2} out */ @@ -4806,8 +4222,8 @@ function multiplyScalar(out, a, b) { * Adds two mat2's after multiplying each element of the second operand by a scalar value. * * @param {mat2} out the receiving vector - * @param {mat2} a the first operand - * @param {mat2} b the second operand + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand * @param {Number} scale the amount to scale b's elements by before adding * @returns {mat2} out */ @@ -4835,9 +4251,11 @@ var mul = multiply; exports.mul = mul; var sub = subtract; exports.sub = sub; -},{"./common.js":22}],25:[function(require,module,exports){ +},{"./common.js":21}],24:[function(require,module,exports){ "use strict"; +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + Object.defineProperty(exports, "__esModule", { value: true }); @@ -4868,17 +4286,19 @@ exports.sub = exports.mul = void 0; var glMatrix = _interopRequireWildcard(require("./common.js")); -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } } +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 2x3 Matrix * @module mat2d - * * @description * A mat2d contains six elements defined as: *
- * [a, b, c,
- *  d, tx, ty]
+ * [a, b,
+ *  c, d,
+ *  tx, ty]
  * 
* This is a short form for the 3x3 matrix: *
@@ -4911,7 +4331,7 @@ function create() {
 /**
  * Creates a new mat2d initialized with values from an existing matrix
  *
- * @param {mat2d} a matrix to clone
+ * @param {ReadonlyMat2d} a matrix to clone
  * @returns {mat2d} a new 2x3 matrix
  */
 
@@ -4930,7 +4350,7 @@ function clone(a) {
  * Copy the values from one mat2d to another
  *
  * @param {mat2d} out the receiving matrix
- * @param {mat2d} a the source matrix
+ * @param {ReadonlyMat2d} a the source matrix
  * @returns {mat2d} out
  */
 
@@ -5011,7 +4431,7 @@ function set(out, a, b, c, d, tx, ty) {
  * Inverts a mat2d
  *
  * @param {mat2d} out the receiving matrix
- * @param {mat2d} a the source matrix
+ * @param {ReadonlyMat2d} a the source matrix
  * @returns {mat2d} out
  */
 
@@ -5041,7 +4461,7 @@ function invert(out, a) {
 /**
  * Calculates the determinant of a mat2d
  *
- * @param {mat2d} a the source matrix
+ * @param {ReadonlyMat2d} a the source matrix
  * @returns {Number} determinant of a
  */
 
@@ -5053,8 +4473,8 @@ function determinant(a) {
  * Multiplies two mat2d's
  *
  * @param {mat2d} out the receiving matrix
- * @param {mat2d} a the first operand
- * @param {mat2d} b the second operand
+ * @param {ReadonlyMat2d} a the first operand
+ * @param {ReadonlyMat2d} b the second operand
  * @returns {mat2d} out
  */
 
@@ -5084,7 +4504,7 @@ function multiply(out, a, b) {
  * Rotates a mat2d by the given angle
  *
  * @param {mat2d} out the receiving matrix
- * @param {mat2d} a the matrix to rotate
+ * @param {ReadonlyMat2d} a the matrix to rotate
  * @param {Number} rad the angle to rotate the matrix by
  * @returns {mat2d} out
  */
@@ -5111,8 +4531,8 @@ function rotate(out, a, rad) {
  * Scales the mat2d by the dimensions in the given vec2
  *
  * @param {mat2d} out the receiving matrix
- * @param {mat2d} a the matrix to translate
- * @param {vec2} v the vec2 to scale the matrix by
+ * @param {ReadonlyMat2d} a the matrix to translate
+ * @param {ReadonlyVec2} v the vec2 to scale the matrix by
  * @returns {mat2d} out
  **/
 
@@ -5138,8 +4558,8 @@ function scale(out, a, v) {
  * Translates the mat2d by the dimensions in the given vec2
  *
  * @param {mat2d} out the receiving matrix
- * @param {mat2d} a the matrix to translate
- * @param {vec2} v the vec2 to translate the matrix by
+ * @param {ReadonlyMat2d} a the matrix to translate
+ * @param {ReadonlyVec2} v the vec2 to translate the matrix by
  * @returns {mat2d} out
  **/
 
@@ -5193,7 +4613,7 @@ function fromRotation(out, rad) {
  *     mat2d.scale(dest, dest, vec);
  *
  * @param {mat2d} out mat2d receiving operation result
- * @param {vec2} v Scaling vector
+ * @param {ReadonlyVec2} v Scaling vector
  * @returns {mat2d} out
  */
 
@@ -5215,7 +4635,7 @@ function fromScaling(out, v) {
  *     mat2d.translate(dest, dest, vec);
  *
  * @param {mat2d} out mat2d receiving operation result
- * @param {vec2} v Translation vector
+ * @param {ReadonlyVec2} v Translation vector
  * @returns {mat2d} out
  */
 
@@ -5232,18 +4652,18 @@ function fromTranslation(out, v) {
 /**
  * Returns a string representation of a mat2d
  *
- * @param {mat2d} a matrix to represent as a string
+ * @param {ReadonlyMat2d} a matrix to represent as a string
  * @returns {String} string representation of the matrix
  */
 
 
 function str(a) {
-  return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ')';
+  return "mat2d(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ")";
 }
 /**
  * Returns Frobenius norm of a mat2d
  *
- * @param {mat2d} a the matrix to calculate Frobenius norm of
+ * @param {ReadonlyMat2d} a the matrix to calculate Frobenius norm of
  * @returns {Number} Frobenius norm
  */
 
@@ -5255,8 +4675,8 @@ function frob(a) {
  * Adds two mat2d's
  *
  * @param {mat2d} out the receiving matrix
- * @param {mat2d} a the first operand
- * @param {mat2d} b the second operand
+ * @param {ReadonlyMat2d} a the first operand
+ * @param {ReadonlyMat2d} b the second operand
  * @returns {mat2d} out
  */
 
@@ -5274,8 +4694,8 @@ function add(out, a, b) {
  * Subtracts matrix b from matrix a
  *
  * @param {mat2d} out the receiving matrix
- * @param {mat2d} a the first operand
- * @param {mat2d} b the second operand
+ * @param {ReadonlyMat2d} a the first operand
+ * @param {ReadonlyMat2d} b the second operand
  * @returns {mat2d} out
  */
 
@@ -5293,7 +4713,7 @@ function subtract(out, a, b) {
  * Multiply each element of the matrix by a scalar.
  *
  * @param {mat2d} out the receiving matrix
- * @param {mat2d} a the matrix to scale
+ * @param {ReadonlyMat2d} a the matrix to scale
  * @param {Number} b amount to scale the matrix's elements by
  * @returns {mat2d} out
  */
@@ -5312,8 +4732,8 @@ function multiplyScalar(out, a, b) {
  * Adds two mat2d's after multiplying each element of the second operand by a scalar value.
  *
  * @param {mat2d} out the receiving vector
- * @param {mat2d} a the first operand
- * @param {mat2d} b the second operand
+ * @param {ReadonlyMat2d} a the first operand
+ * @param {ReadonlyMat2d} b the second operand
  * @param {Number} scale the amount to scale b's elements by before adding
  * @returns {mat2d} out
  */
@@ -5331,8 +4751,8 @@ function multiplyScalarAndAdd(out, a, b, scale) {
 /**
  * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
  *
- * @param {mat2d} a The first matrix.
- * @param {mat2d} b The second matrix.
+ * @param {ReadonlyMat2d} a The first matrix.
+ * @param {ReadonlyMat2d} b The second matrix.
  * @returns {Boolean} True if the matrices are equal, false otherwise.
  */
 
@@ -5343,8 +4763,8 @@ function exactEquals(a, b) {
 /**
  * Returns whether or not the matrices have approximately the same elements in the same position.
  *
- * @param {mat2d} a The first matrix.
- * @param {mat2d} b The second matrix.
+ * @param {ReadonlyMat2d} a The first matrix.
+ * @param {ReadonlyMat2d} b The second matrix.
  * @returns {Boolean} True if the matrices are equal, false otherwise.
  */
 
@@ -5379,9 +4799,11 @@ var mul = multiply;
 exports.mul = mul;
 var sub = subtract;
 exports.sub = sub;
-},{"./common.js":22}],26:[function(require,module,exports){
+},{"./common.js":21}],25:[function(require,module,exports){
 "use strict";
 
+function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -5419,7 +4841,9 @@ exports.sub = exports.mul = void 0;
 
 var glMatrix = _interopRequireWildcard(require("./common.js"));
 
-function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } }
+function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
+
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
 
 /**
  * 3x3 Matrix
@@ -5452,7 +4876,7 @@ function create() {
  * Copies the upper-left 3x3 values into the given mat3.
  *
  * @param {mat3} out the receiving 3x3 matrix
- * @param {mat4} a   the source 4x4 matrix
+ * @param {ReadonlyMat4} a   the source 4x4 matrix
  * @returns {mat3} out
  */
 
@@ -5472,7 +4896,7 @@ function fromMat4(out, a) {
 /**
  * Creates a new mat3 initialized with values from an existing matrix
  *
- * @param {mat3} a matrix to clone
+ * @param {ReadonlyMat3} a matrix to clone
  * @returns {mat3} a new 3x3 matrix
  */
 
@@ -5494,7 +4918,7 @@ function clone(a) {
  * Copy the values from one mat3 to another
  *
  * @param {mat3} out the receiving matrix
- * @param {mat3} a the source matrix
+ * @param {ReadonlyMat3} a the source matrix
  * @returns {mat3} out
  */
 
@@ -5593,7 +5017,7 @@ function identity(out) {
  * Transpose the values of a mat3
  *
  * @param {mat3} out the receiving matrix
- * @param {mat3} a the source matrix
+ * @param {ReadonlyMat3} a the source matrix
  * @returns {mat3} out
  */
 
@@ -5628,7 +5052,7 @@ function transpose(out, a) {
  * Inverts a mat3
  *
  * @param {mat3} out the receiving matrix
- * @param {mat3} a the source matrix
+ * @param {ReadonlyMat3} a the source matrix
  * @returns {mat3} out
  */
 
@@ -5669,7 +5093,7 @@ function invert(out, a) {
  * Calculates the adjugate of a mat3
  *
  * @param {mat3} out the receiving matrix
- * @param {mat3} a the source matrix
+ * @param {ReadonlyMat3} a the source matrix
  * @returns {mat3} out
  */
 
@@ -5698,7 +5122,7 @@ function adjoint(out, a) {
 /**
  * Calculates the determinant of a mat3
  *
- * @param {mat3} a the source matrix
+ * @param {ReadonlyMat3} a the source matrix
  * @returns {Number} determinant of a
  */
 
@@ -5719,8 +5143,8 @@ function determinant(a) {
  * Multiplies two mat3's
  *
  * @param {mat3} out the receiving matrix
- * @param {mat3} a the first operand
- * @param {mat3} b the second operand
+ * @param {ReadonlyMat3} a the first operand
+ * @param {ReadonlyMat3} b the second operand
  * @returns {mat3} out
  */
 
@@ -5759,8 +5183,8 @@ function multiply(out, a, b) {
  * Translate a mat3 by the given vector
  *
  * @param {mat3} out the receiving matrix
- * @param {mat3} a the matrix to translate
- * @param {vec2} v vector to translate by
+ * @param {ReadonlyMat3} a the matrix to translate
+ * @param {ReadonlyVec2} v vector to translate by
  * @returns {mat3} out
  */
 
@@ -5792,7 +5216,7 @@ function translate(out, a, v) {
  * Rotates a mat3 by the given angle
  *
  * @param {mat3} out the receiving matrix
- * @param {mat3} a the matrix to rotate
+ * @param {ReadonlyMat3} a the matrix to rotate
  * @param {Number} rad the angle to rotate the matrix by
  * @returns {mat3} out
  */
@@ -5821,17 +5245,16 @@ function rotate(out, a, rad) {
   out[8] = a22;
   return out;
 }
-
-;
 /**
  * Scales the mat3 by the dimensions in the given vec2
  *
  * @param {mat3} out the receiving matrix
- * @param {mat3} a the matrix to rotate
- * @param {vec2} v the vec2 to scale the matrix by
+ * @param {ReadonlyMat3} a the matrix to rotate
+ * @param {ReadonlyVec2} v the vec2 to scale the matrix by
  * @returns {mat3} out
  **/
 
+
 function scale(out, a, v) {
   var x = v[0],
       y = v[1];
@@ -5854,7 +5277,7 @@ function scale(out, a, v) {
  *     mat3.translate(dest, dest, vec);
  *
  * @param {mat3} out mat3 receiving operation result
- * @param {vec2} v Translation vector
+ * @param {ReadonlyVec2} v Translation vector
  * @returns {mat3} out
  */
 
@@ -5906,7 +5329,7 @@ function fromRotation(out, rad) {
  *     mat3.scale(dest, dest, vec);
  *
  * @param {mat3} out mat3 receiving operation result
- * @param {vec2} v Scaling vector
+ * @param {ReadonlyVec2} v Scaling vector
  * @returns {mat3} out
  */
 
@@ -5927,7 +5350,7 @@ function fromScaling(out, v) {
  * Copies the values from a mat2d into a mat3
  *
  * @param {mat3} out the receiving matrix
- * @param {mat2d} a the matrix to copy
+ * @param {ReadonlyMat2d} a the matrix to copy
  * @returns {mat3} out
  **/
 
@@ -5945,13 +5368,13 @@ function fromMat2d(out, a) {
   return out;
 }
 /**
-* Calculates a 3x3 matrix from the given quaternion
-*
-* @param {mat3} out mat3 receiving operation result
-* @param {quat} q Quaternion to create matrix from
-*
-* @returns {mat3} out
-*/
+ * Calculates a 3x3 matrix from the given quaternion
+ *
+ * @param {mat3} out mat3 receiving operation result
+ * @param {ReadonlyQuat} q Quaternion to create matrix from
+ *
+ * @returns {mat3} out
+ */
 
 
 function fromQuat(out, q) {
@@ -5983,13 +5406,13 @@ function fromQuat(out, q) {
   return out;
 }
 /**
-* Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
-*
-* @param {mat3} out mat3 receiving operation result
-* @param {mat4} a Mat4 to derive the normal matrix from
-*
-* @returns {mat3} out
-*/
+ * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
+ *
+ * @param {mat3} out mat3 receiving operation result
+ * @param {ReadonlyMat4} a Mat4 to derive the normal matrix from
+ *
+ * @returns {mat3} out
+ */
 
 
 function normalFromMat4(out, a) {
@@ -6065,18 +5488,18 @@ function projection(out, width, height) {
 /**
  * Returns a string representation of a mat3
  *
- * @param {mat3} a matrix to represent as a string
+ * @param {ReadonlyMat3} a matrix to represent as a string
  * @returns {String} string representation of the matrix
  */
 
 
 function str(a) {
-  return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + a[8] + ')';
+  return "mat3(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ")";
 }
 /**
  * Returns Frobenius norm of a mat3
  *
- * @param {mat3} a the matrix to calculate Frobenius norm of
+ * @param {ReadonlyMat3} a the matrix to calculate Frobenius norm of
  * @returns {Number} Frobenius norm
  */
 
@@ -6088,8 +5511,8 @@ function frob(a) {
  * Adds two mat3's
  *
  * @param {mat3} out the receiving matrix
- * @param {mat3} a the first operand
- * @param {mat3} b the second operand
+ * @param {ReadonlyMat3} a the first operand
+ * @param {ReadonlyMat3} b the second operand
  * @returns {mat3} out
  */
 
@@ -6110,8 +5533,8 @@ function add(out, a, b) {
  * Subtracts matrix b from matrix a
  *
  * @param {mat3} out the receiving matrix
- * @param {mat3} a the first operand
- * @param {mat3} b the second operand
+ * @param {ReadonlyMat3} a the first operand
+ * @param {ReadonlyMat3} b the second operand
  * @returns {mat3} out
  */
 
@@ -6132,7 +5555,7 @@ function subtract(out, a, b) {
  * Multiply each element of the matrix by a scalar.
  *
  * @param {mat3} out the receiving matrix
- * @param {mat3} a the matrix to scale
+ * @param {ReadonlyMat3} a the matrix to scale
  * @param {Number} b amount to scale the matrix's elements by
  * @returns {mat3} out
  */
@@ -6154,8 +5577,8 @@ function multiplyScalar(out, a, b) {
  * Adds two mat3's after multiplying each element of the second operand by a scalar value.
  *
  * @param {mat3} out the receiving vector
- * @param {mat3} a the first operand
- * @param {mat3} b the second operand
+ * @param {ReadonlyMat3} a the first operand
+ * @param {ReadonlyMat3} b the second operand
  * @param {Number} scale the amount to scale b's elements by before adding
  * @returns {mat3} out
  */
@@ -6176,8 +5599,8 @@ function multiplyScalarAndAdd(out, a, b, scale) {
 /**
  * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
  *
- * @param {mat3} a The first matrix.
- * @param {mat3} b The second matrix.
+ * @param {ReadonlyMat3} a The first matrix.
+ * @param {ReadonlyMat3} b The second matrix.
  * @returns {Boolean} True if the matrices are equal, false otherwise.
  */
 
@@ -6188,8 +5611,8 @@ function exactEquals(a, b) {
 /**
  * Returns whether or not the matrices have approximately the same elements in the same position.
  *
- * @param {mat3} a The first matrix.
- * @param {mat3} b The second matrix.
+ * @param {ReadonlyMat3} a The first matrix.
+ * @param {ReadonlyMat3} b The second matrix.
  * @returns {Boolean} True if the matrices are equal, false otherwise.
  */
 
@@ -6230,9 +5653,11 @@ var mul = multiply;
 exports.mul = mul;
 var sub = subtract;
 exports.sub = sub;
-},{"./common.js":22}],27:[function(require,module,exports){
+},{"./common.js":21}],26:[function(require,module,exports){
 "use strict";
 
+function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -6285,7 +5710,9 @@ exports.sub = exports.mul = void 0;
 
 var glMatrix = _interopRequireWildcard(require("./common.js"));
 
-function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } }
+function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
+
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
 
 /**
  * 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied. @@ -6324,7 +5751,7 @@ function create() { /** * Creates a new mat4 initialized with values from an existing matrix * - * @param {mat4} a matrix to clone + * @param {ReadonlyMat4} a matrix to clone * @returns {mat4} a new 4x4 matrix */ @@ -6353,7 +5780,7 @@ function clone(a) { * Copy the values from one mat4 to another * * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix + * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ @@ -6494,7 +5921,7 @@ function identity(out) { * Transpose the values of a mat4 * * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix + * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ @@ -6545,7 +5972,7 @@ function transpose(out, a) { * Inverts a mat4 * * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix + * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ @@ -6609,7 +6036,7 @@ function invert(out, a) { * Calculates the adjugate of a mat4 * * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix + * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ @@ -6652,7 +6079,7 @@ function adjoint(out, a) { /** * Calculates the determinant of a mat4 * - * @param {mat4} a the source matrix + * @param {ReadonlyMat4} a the source matrix * @returns {Number} determinant of a */ @@ -6693,8 +6120,8 @@ function determinant(a) { * Multiplies two mat4s * * @param {mat4} out the receiving matrix - * @param {mat4} a the first operand - * @param {mat4} b the second operand + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand * @returns {mat4} out */ @@ -6755,8 +6182,8 @@ function multiply(out, a, b) { * Translate a mat4 by the given vector * * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to translate - * @param {vec3} v vector to translate by + * @param {ReadonlyMat4} a the matrix to translate + * @param {ReadonlyVec3} v vector to translate by * @returns {mat4} out */ @@ -6811,8 +6238,8 @@ function translate(out, a, v) { * Scales the mat4 by the dimensions in the given vec3 not using vectorization * * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to scale - * @param {vec3} v the vec3 to scale the matrix by + * @param {ReadonlyMat4} a the matrix to scale + * @param {ReadonlyVec3} v the vec3 to scale the matrix by * @returns {mat4} out **/ @@ -6843,9 +6270,9 @@ function scale(out, a, v) { * Rotates a mat4 by the given angle around the given axis * * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate + * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by - * @param {vec3} axis the axis to rotate around + * @param {ReadonlyVec3} axis the axis to rotate around * @returns {mat4} out */ @@ -6924,7 +6351,7 @@ function rotate(out, a, rad, axis) { * Rotates a matrix by the given angle around the X axis * * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate + * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ @@ -6969,7 +6396,7 @@ function rotateX(out, a, rad) { * Rotates a matrix by the given angle around the Y axis * * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate + * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ @@ -7014,7 +6441,7 @@ function rotateY(out, a, rad) { * Rotates a matrix by the given angle around the Z axis * * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate + * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ @@ -7063,7 +6490,7 @@ function rotateZ(out, a, rad) { * mat4.translate(dest, dest, vec); * * @param {mat4} out mat4 receiving operation result - * @param {vec3} v Translation vector + * @param {ReadonlyVec3} v Translation vector * @returns {mat4} out */ @@ -7095,7 +6522,7 @@ function fromTranslation(out, v) { * mat4.scale(dest, dest, vec); * * @param {mat4} out mat4 receiving operation result - * @param {vec3} v Scaling vector + * @param {ReadonlyVec3} v Scaling vector * @returns {mat4} out */ @@ -7128,7 +6555,7 @@ function fromScaling(out, v) { * * @param {mat4} out mat4 receiving operation result * @param {Number} rad the angle to rotate the matrix by - * @param {vec3} axis the axis to rotate around + * @param {ReadonlyVec3} axis the axis to rotate around * @returns {mat4} out */ @@ -7287,7 +6714,7 @@ function fromZRotation(out, rad) { * * @param {mat4} out mat4 receiving operation result * @param {quat4} q Rotation quaternion - * @param {vec3} v Translation vector + * @param {ReadonlyVec3} v Translation vector * @returns {mat4} out */ @@ -7332,7 +6759,7 @@ function fromRotationTranslation(out, q, v) { * Creates a new mat4 from a dual quat. * * @param {mat4} out Matrix - * @param {quat2} a Dual Quaternion + * @param {ReadonlyQuat2} a Dual Quaternion * @returns {mat4} mat4 receiving operation result */ @@ -7368,7 +6795,7 @@ function fromQuat2(out, a) { * the returned vector will be the same as the translation vector * originally supplied. * @param {vec3} out Vector to receive translation component - * @param {mat4} mat Matrix to be decomposed (input) + * @param {ReadonlyMat4} mat Matrix to be decomposed (input) * @return {vec3} out */ @@ -7386,7 +6813,7 @@ function getTranslation(out, mat) { * the same as the scaling vector * originally supplied. * @param {vec3} out Vector to receive scaling factor component - * @param {mat4} mat Matrix to be decomposed (input) + * @param {ReadonlyMat4} mat Matrix to be decomposed (input) * @return {vec3} out */ @@ -7412,7 +6839,7 @@ function getScaling(out, mat) { * fromRotationTranslation, the returned quaternion will be the * same as the quaternion originally supplied. * @param {quat} out Quaternion to receive the rotation component - * @param {mat4} mat Matrix to be decomposed (input) + * @param {ReadonlyMat4} mat Matrix to be decomposed (input) * @return {quat} out */ @@ -7476,8 +6903,8 @@ function getRotation(out, mat) { * * @param {mat4} out mat4 receiving operation result * @param {quat4} q Rotation quaternion - * @param {vec3} v Translation vector - * @param {vec3} s Scaling vector + * @param {ReadonlyVec3} v Translation vector + * @param {ReadonlyVec3} s Scaling vector * @returns {mat4} out */ @@ -7536,9 +6963,9 @@ function fromRotationTranslationScale(out, q, v, s) { * * @param {mat4} out mat4 receiving operation result * @param {quat4} q Rotation quaternion - * @param {vec3} v Translation vector - * @param {vec3} s Scaling vector - * @param {vec3} o The origin vector around which to scale and rotate + * @param {ReadonlyVec3} v Translation vector + * @param {ReadonlyVec3} s Scaling vector + * @param {ReadonlyVec3} o The origin vector around which to scale and rotate * @returns {mat4} out */ @@ -7598,7 +7025,7 @@ function fromRotationTranslationScaleOrigin(out, q, v, s, o) { * Calculates a 4x4 matrix from the given quaternion * * @param {mat4} out mat4 receiving operation result - * @param {quat} q Quaternion to create matrix from + * @param {ReadonlyQuat} q Quaternion to create matrix from * * @returns {mat4} out */ @@ -7796,9 +7223,9 @@ function ortho(out, left, right, bottom, top, near, far) { * If you want a matrix that actually makes an object look at another object, you should use targetTo instead. * * @param {mat4} out mat4 frustum matrix will be written into - * @param {vec3} eye Position of the viewer - * @param {vec3} center Point the viewer is looking at - * @param {vec3} up vec3 pointing up + * @param {ReadonlyVec3} eye Position of the viewer + * @param {ReadonlyVec3} center Point the viewer is looking at + * @param {ReadonlyVec3} up vec3 pointing up * @returns {mat4} out */ @@ -7880,9 +7307,9 @@ function lookAt(out, eye, center, up) { * Generates a matrix that makes something look at something else. * * @param {mat4} out mat4 frustum matrix will be written into - * @param {vec3} eye Position of the viewer - * @param {vec3} center Point the viewer is looking at - * @param {vec3} up vec3 pointing up + * @param {ReadonlyVec3} eye Position of the viewer + * @param {ReadonlyVec3} center Point the viewer is looking at + * @param {ReadonlyVec3} up vec3 pointing up * @returns {mat4} out */ @@ -7936,35 +7363,34 @@ function targetTo(out, eye, target, up) { out[15] = 1; return out; } - -; /** * Returns a string representation of a mat4 * - * @param {mat4} a matrix to represent as a string + * @param {ReadonlyMat4} a matrix to represent as a string * @returns {String} string representation of the matrix */ + function str(a) { - return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' + a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')'; + return "mat4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + ")"; } /** * Returns Frobenius norm of a mat4 * - * @param {mat4} a the matrix to calculate Frobenius norm of + * @param {ReadonlyMat4} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ function frob(a) { - return Math.hypot(a[0], a[1], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); + return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); } /** * Adds two mat4's * * @param {mat4} out the receiving matrix - * @param {mat4} a the first operand - * @param {mat4} b the second operand + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand * @returns {mat4} out */ @@ -7992,8 +7418,8 @@ function add(out, a, b) { * Subtracts matrix b from matrix a * * @param {mat4} out the receiving matrix - * @param {mat4} a the first operand - * @param {mat4} b the second operand + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand * @returns {mat4} out */ @@ -8021,7 +7447,7 @@ function subtract(out, a, b) { * Multiply each element of the matrix by a scalar. * * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to scale + * @param {ReadonlyMat4} a the matrix to scale * @param {Number} b amount to scale the matrix's elements by * @returns {mat4} out */ @@ -8050,8 +7476,8 @@ function multiplyScalar(out, a, b) { * Adds two mat4's after multiplying each element of the second operand by a scalar value. * * @param {mat4} out the receiving vector - * @param {mat4} a the first operand - * @param {mat4} b the second operand + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand * @param {Number} scale the amount to scale b's elements by before adding * @returns {mat4} out */ @@ -8079,8 +7505,8 @@ function multiplyScalarAndAdd(out, a, b, scale) { /** * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) * - * @param {mat4} a The first matrix. - * @param {mat4} b The second matrix. + * @param {ReadonlyMat4} a The first matrix. + * @param {ReadonlyMat4} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ @@ -8091,8 +7517,8 @@ function exactEquals(a, b) { /** * Returns whether or not the matrices have approximately the same elements in the same position. * - * @param {mat4} a The first matrix. - * @param {mat4} b The second matrix. + * @param {ReadonlyMat4} a The first matrix. + * @param {ReadonlyMat4} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ @@ -8147,9 +7573,11 @@ var mul = multiply; exports.mul = mul; var sub = subtract; exports.sub = sub; -},{"./common.js":22}],28:[function(require,module,exports){ +},{"./common.js":21}],27:[function(require,module,exports){ "use strict"; +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + Object.defineProperty(exports, "__esModule", { value: true }); @@ -8183,7 +7611,9 @@ var vec3 = _interopRequireWildcard(require("./vec3.js")); var vec4 = _interopRequireWildcard(require("./vec4.js")); -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } } +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * Quaternion @@ -8227,7 +7657,7 @@ function identity(out) { * then returns it. * * @param {quat} out the receiving quaternion - * @param {vec3} axis the axis around which to rotate + * @param {ReadonlyVec3} axis the axis around which to rotate * @param {Number} rad the angle in radians * @returns {quat} out **/ @@ -8252,7 +7682,7 @@ function setAxisAngle(out, axis, rad) { * angle -90 is the same as the quaternion formed by * [0, 0, 1] and 270. This method favors the latter. * @param {vec3} out_axis Vector receiving the axis of rotation - * @param {quat} q Quaternion to be decomposed + * @param {ReadonlyQuat} q Quaternion to be decomposed * @return {Number} Angle, in radians, of the rotation */ @@ -8277,8 +7707,8 @@ function getAxisAngle(out_axis, q) { /** * Gets the angular distance between two unit quaternions * - * @param {quat} a Origin unit quaternion - * @param {quat} b Destination unit quaternion + * @param {ReadonlyQuat} a Origin unit quaternion + * @param {ReadonlyQuat} b Destination unit quaternion * @return {Number} Angle, in radians, between the two quaternions */ @@ -8291,8 +7721,8 @@ function getAngle(a, b) { * Multiplies two quat's * * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand * @returns {quat} out */ @@ -8316,7 +7746,7 @@ function multiply(out, a, b) { * Rotates a quaternion by the given angle about the X axis * * @param {quat} out quat receiving operation result - * @param {quat} a quat to rotate + * @param {ReadonlyQuat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ @@ -8340,7 +7770,7 @@ function rotateX(out, a, rad) { * Rotates a quaternion by the given angle about the Y axis * * @param {quat} out quat receiving operation result - * @param {quat} a quat to rotate + * @param {ReadonlyQuat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ @@ -8364,7 +7794,7 @@ function rotateY(out, a, rad) { * Rotates a quaternion by the given angle about the Z axis * * @param {quat} out quat receiving operation result - * @param {quat} a quat to rotate + * @param {ReadonlyQuat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ @@ -8390,7 +7820,7 @@ function rotateZ(out, a, rad) { * Any existing W component will be ignored. * * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate W component of + * @param {ReadonlyQuat} a quat to calculate W component of * @returns {quat} out */ @@ -8409,7 +7839,7 @@ function calculateW(out, a) { * Calculate the exponential of a unit quaternion. * * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate the exponential of + * @param {ReadonlyQuat} a quat to calculate the exponential of * @returns {quat} out */ @@ -8432,7 +7862,7 @@ function exp(out, a) { * Calculate the natural logarithm of a unit quaternion. * * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate the exponential of + * @param {ReadonlyQuat} a quat to calculate the exponential of * @returns {quat} out */ @@ -8454,7 +7884,7 @@ function ln(out, a) { * Calculate the scalar power of a unit quaternion. * * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate the exponential of + * @param {ReadonlyQuat} a quat to calculate the exponential of * @param {Number} b amount to scale the quaternion by * @returns {quat} out */ @@ -8470,8 +7900,8 @@ function pow(out, a, b) { * Performs a spherical linear interpolation between two quat * * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out */ @@ -8523,7 +7953,7 @@ function slerp(out, a, b, t) { } /** * Generates a random unit quaternion - * + * * @param {quat} out the receiving quaternion * @returns {quat} out */ @@ -8547,7 +7977,7 @@ function random(out) { * Calculates the inverse of a quat * * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate inverse of + * @param {ReadonlyQuat} a quat to calculate inverse of * @returns {quat} out */ @@ -8571,7 +8001,7 @@ function invert(out, a) { * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. * * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate conjugate of + * @param {ReadonlyQuat} a quat to calculate conjugate of * @returns {quat} out */ @@ -8590,7 +8020,7 @@ function conjugate(out, a) { * to renormalize the quaternion yourself where necessary. * * @param {quat} out the receiving quaternion - * @param {mat3} m rotation matrix + * @param {ReadonlyMat3} m rotation matrix * @returns {quat} out * @function */ @@ -8661,18 +8091,18 @@ function fromEuler(out, x, y, z) { /** * Returns a string representation of a quatenion * - * @param {quat} a vector to represent as a string + * @param {ReadonlyQuat} a vector to represent as a string * @returns {String} string representation of the vector */ function str(a) { - return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; + return "quat(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; } /** * Creates a new quat initialized with values from an existing quaternion * - * @param {quat} a quaternion to clone + * @param {ReadonlyQuat} a quaternion to clone * @returns {quat} a new quaternion * @function */ @@ -8696,7 +8126,7 @@ var fromValues = vec4.fromValues; * Copy the values from one quat to another * * @param {quat} out the receiving quaternion - * @param {quat} a the source quaternion + * @param {ReadonlyQuat} a the source quaternion * @returns {quat} out * @function */ @@ -8721,8 +8151,8 @@ var set = vec4.set; * Adds two quat's * * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand * @returns {quat} out * @function */ @@ -8740,7 +8170,7 @@ var mul = multiply; * Scales a quat by a scalar number * * @param {quat} out the receiving vector - * @param {quat} a the vector to scale + * @param {ReadonlyQuat} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {quat} out * @function @@ -8751,8 +8181,8 @@ var scale = vec4.scale; /** * Calculates the dot product of two quat's * - * @param {quat} a the first operand - * @param {quat} b the second operand + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand * @returns {Number} dot product of a and b * @function */ @@ -8763,8 +8193,8 @@ var dot = vec4.dot; * Performs a linear interpolation between two quat's * * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out * @function @@ -8775,7 +8205,7 @@ var lerp = vec4.lerp; /** * Calculates the length of a quat * - * @param {quat} a vector to calculate length of + * @param {ReadonlyQuat} a vector to calculate length of * @returns {Number} length of a */ @@ -8791,7 +8221,7 @@ var len = length; /** * Calculates the squared length of a quat * - * @param {quat} a vector to calculate squared length of + * @param {ReadonlyQuat} a vector to calculate squared length of * @returns {Number} squared length of a * @function */ @@ -8809,7 +8239,7 @@ var sqrLen = squaredLength; * Normalize a quat * * @param {quat} out the receiving quaternion - * @param {quat} a quaternion to normalize + * @param {ReadonlyQuat} a quaternion to normalize * @returns {quat} out * @function */ @@ -8819,8 +8249,8 @@ var normalize = vec4.normalize; /** * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===) * - * @param {quat} a The first quaternion. - * @param {quat} b The second quaternion. + * @param {ReadonlyQuat} a The first quaternion. + * @param {ReadonlyQuat} b The second quaternion. * @returns {Boolean} True if the vectors are equal, false otherwise. */ @@ -8829,8 +8259,8 @@ var exactEquals = vec4.exactEquals; /** * Returns whether or not the quaternions have approximately the same elements in the same position. * - * @param {quat} a The first vector. - * @param {quat} b The second vector. + * @param {ReadonlyQuat} a The first vector. + * @param {ReadonlyQuat} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ @@ -8843,8 +8273,8 @@ var equals = vec4.equals; * Both vectors are assumed to be unit length. * * @param {quat} out the receiving quaternion. - * @param {vec3} a the initial vector - * @param {vec3} b the destination vector + * @param {ReadonlyVec3} a the initial vector + * @param {ReadonlyVec3} b the destination vector * @returns {quat} out */ @@ -8883,10 +8313,10 @@ var rotationTo = function () { * Performs a spherical linear interpolation with two control points * * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand - * @param {quat} c the third operand - * @param {quat} d the fourth operand + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {ReadonlyQuat} c the third operand + * @param {ReadonlyQuat} d the fourth operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out */ @@ -8909,9 +8339,9 @@ var sqlerp = function () { * axes. Each axis is a vec3 and is expected to be unit length and * perpendicular to all other specified axes. * - * @param {vec3} view the vector representing the viewing direction - * @param {vec3} right the vector representing the local "right" direction - * @param {vec3} up the vector representing the local "up" direction + * @param {ReadonlyVec3} view the vector representing the viewing direction + * @param {ReadonlyVec3} right the vector representing the local "right" direction + * @param {ReadonlyVec3} up the vector representing the local "up" direction * @returns {quat} out */ @@ -8935,9 +8365,11 @@ var setAxes = function () { }(); exports.setAxes = setAxes; -},{"./common.js":22,"./mat3.js":26,"./vec3.js":31,"./vec4.js":32}],29:[function(require,module,exports){ +},{"./common.js":21,"./mat3.js":25,"./vec3.js":30,"./vec4.js":31}],28:[function(require,module,exports){ "use strict"; +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + Object.defineProperty(exports, "__esModule", { value: true }); @@ -8980,7 +8412,9 @@ var quat = _interopRequireWildcard(require("./quat.js")); var mat4 = _interopRequireWildcard(require("./mat4.js")); -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } } +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * Dual Quaternion
@@ -9014,7 +8448,7 @@ function create() { /** * Creates a new quat initialized with values from an existing quaternion * - * @param {quat2} a dual quaternion to clone + * @param {ReadonlyQuat2} a dual quaternion to clone * @returns {quat2} new dual quaternion * @function */ @@ -9093,9 +8527,9 @@ function fromRotationTranslationValues(x1, y1, z1, w1, x2, y2, z2) { /** * Creates a dual quat from a quaternion and a translation * - * @param {quat2} dual quaternion receiving operation result - * @param {quat} q a normalized quaternion - * @param {vec3} t tranlation vector + * @param {ReadonlyQuat2} dual quaternion receiving operation result + * @param {ReadonlyQuat} q a normalized quaternion + * @param {ReadonlyVec3} t tranlation vector * @returns {quat2} dual quaternion receiving operation result * @function */ @@ -9122,8 +8556,8 @@ function fromRotationTranslation(out, q, t) { /** * Creates a dual quat from a translation * - * @param {quat2} dual quaternion receiving operation result - * @param {vec3} t translation vector + * @param {ReadonlyQuat2} dual quaternion receiving operation result + * @param {ReadonlyVec3} t translation vector * @returns {quat2} dual quaternion receiving operation result * @function */ @@ -9143,8 +8577,8 @@ function fromTranslation(out, t) { /** * Creates a dual quat from a quaternion * - * @param {quat2} dual quaternion receiving operation result - * @param {quat} q the quaternion + * @param {ReadonlyQuat2} dual quaternion receiving operation result + * @param {ReadonlyQuat} q the quaternion * @returns {quat2} dual quaternion receiving operation result * @function */ @@ -9165,7 +8599,7 @@ function fromRotation(out, q) { * Creates a new dual quat from a matrix (4x4) * * @param {quat2} out the dual quaternion - * @param {mat4} a the matrix + * @param {ReadonlyMat4} a the matrix * @returns {quat2} dual quat receiving operation result * @function */ @@ -9184,7 +8618,7 @@ function fromMat4(out, a) { * Copy the values from one dual quat to another * * @param {quat2} out the receiving dual quaternion - * @param {quat2} a the source dual quaternion + * @param {ReadonlyQuat2} a the source dual quaternion * @returns {quat2} out * @function */ @@ -9251,7 +8685,7 @@ function set(out, x1, y1, z1, w1, x2, y2, z2, w2) { /** * Gets the real part of a dual quat * @param {quat} out real part - * @param {quat2} a Dual Quaternion + * @param {ReadonlyQuat2} a Dual Quaternion * @return {quat} real part */ @@ -9260,7 +8694,7 @@ var getReal = quat.copy; /** * Gets the dual part of a dual quat * @param {quat} out dual part - * @param {quat2} a Dual Quaternion + * @param {ReadonlyQuat2} a Dual Quaternion * @return {quat} dual part */ @@ -9277,7 +8711,7 @@ function getDual(out, a) { * Set the real component of a dual quat to the given quaternion * * @param {quat2} out the receiving quaternion - * @param {quat} q a quaternion representing the real part + * @param {ReadonlyQuat} q a quaternion representing the real part * @returns {quat2} out * @function */ @@ -9288,7 +8722,7 @@ var setReal = quat.copy; * Set the dual component of a dual quat to the given quaternion * * @param {quat2} out the receiving quaternion - * @param {quat} q a quaternion representing the dual part + * @param {ReadonlyQuat} q a quaternion representing the dual part * @returns {quat2} out * @function */ @@ -9305,7 +8739,7 @@ function setDual(out, q) { /** * Gets the translation of a normalized dual quat * @param {vec3} out translation - * @param {quat2} a Dual Quaternion to be decomposed + * @param {ReadonlyQuat2} a Dual Quaternion to be decomposed * @return {vec3} translation */ @@ -9328,8 +8762,8 @@ function getTranslation(out, a) { * Translates a dual quat by the given vector * * @param {quat2} out the receiving dual quaternion - * @param {quat2} a the dual quaternion to translate - * @param {vec3} v vector to translate by + * @param {ReadonlyQuat2} a the dual quaternion to translate + * @param {ReadonlyVec3} v vector to translate by * @returns {quat2} out */ @@ -9360,7 +8794,7 @@ function translate(out, a, v) { * Rotates a dual quat around the X axis * * @param {quat2} out the receiving dual quaternion - * @param {quat2} a the dual quaternion to rotate + * @param {ReadonlyQuat2} a the dual quaternion to rotate * @param {number} rad how far should the rotation be * @returns {quat2} out */ @@ -9394,7 +8828,7 @@ function rotateX(out, a, rad) { * Rotates a dual quat around the Y axis * * @param {quat2} out the receiving dual quaternion - * @param {quat2} a the dual quaternion to rotate + * @param {ReadonlyQuat2} a the dual quaternion to rotate * @param {number} rad how far should the rotation be * @returns {quat2} out */ @@ -9428,7 +8862,7 @@ function rotateY(out, a, rad) { * Rotates a dual quat around the Z axis * * @param {quat2} out the receiving dual quaternion - * @param {quat2} a the dual quaternion to rotate + * @param {ReadonlyQuat2} a the dual quaternion to rotate * @param {number} rad how far should the rotation be * @returns {quat2} out */ @@ -9462,8 +8896,8 @@ function rotateZ(out, a, rad) { * Rotates a dual quat by a given quaternion (a * q) * * @param {quat2} out the receiving dual quaternion - * @param {quat2} a the dual quaternion to rotate - * @param {quat} q quaternion to rotate by + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {ReadonlyQuat} q quaternion to rotate by * @returns {quat2} out */ @@ -9495,8 +8929,8 @@ function rotateByQuatAppend(out, a, q) { * Rotates a dual quat by a given quaternion (q * a) * * @param {quat2} out the receiving dual quaternion - * @param {quat} q quaternion to rotate by - * @param {quat2} a the dual quaternion to rotate + * @param {ReadonlyQuat} q quaternion to rotate by + * @param {ReadonlyQuat2} a the dual quaternion to rotate * @returns {quat2} out */ @@ -9528,8 +8962,8 @@ function rotateByQuatPrepend(out, q, a) { * Rotates a dual quat around a given axis. Does the normalisation automatically * * @param {quat2} out the receiving dual quaternion - * @param {quat2} a the dual quaternion to rotate - * @param {vec3} axis the axis to rotate around + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {ReadonlyVec3} axis the axis to rotate around * @param {Number} rad how far the rotation should be * @returns {quat2} out */ @@ -9570,8 +9004,8 @@ function rotateAroundAxis(out, a, axis, rad) { * Adds two dual quat's * * @param {quat2} out the receiving dual quaternion - * @param {quat2} a the first operand - * @param {quat2} b the second operand + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand * @returns {quat2} out * @function */ @@ -9592,8 +9026,8 @@ function add(out, a, b) { * Multiplies two dual quat's * * @param {quat2} out the receiving dual quaternion - * @param {quat2} a the first operand - * @param {quat2} b the second operand + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand * @returns {quat2} out */ @@ -9636,7 +9070,7 @@ var mul = multiply; * Scales a dual quat by a scalar number * * @param {quat2} out the receiving dual quat - * @param {quat2} a the dual quat to scale + * @param {ReadonlyQuat2} a the dual quat to scale * @param {Number} b amount to scale the dual quat by * @returns {quat2} out * @function @@ -9658,8 +9092,8 @@ function scale(out, a, b) { /** * Calculates the dot product of two dual quat's (The dot product of the real parts) * - * @param {quat2} a the first operand - * @param {quat2} b the second operand + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand * @returns {Number} dot product of a and b * @function */ @@ -9671,8 +9105,8 @@ var dot = quat.dot; * NOTE: The resulting dual quaternions won't always be normalized (The error is most noticeable when t = 0.5) * * @param {quat2} out the receiving dual quat - * @param {quat2} a the first operand - * @param {quat2} b the second operand + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat2} out */ @@ -9696,7 +9130,7 @@ function lerp(out, a, b, t) { * Calculates the inverse of a dual quat. If they are normalized, conjugate is cheaper * * @param {quat2} out the receiving dual quaternion - * @param {quat2} a dual quat to calculate inverse of + * @param {ReadonlyQuat2} a dual quat to calculate inverse of * @returns {quat2} out */ @@ -9718,7 +9152,7 @@ function invert(out, a) { * If the dual quaternion is normalized, this function is faster than quat2.inverse and produces the same result. * * @param {quat2} out the receiving quaternion - * @param {quat2} a quat to calculate conjugate of + * @param {ReadonlyQuat2} a quat to calculate conjugate of * @returns {quat2} out */ @@ -9737,7 +9171,7 @@ function conjugate(out, a) { /** * Calculates the length of a dual quat * - * @param {quat2} a dual quat to calculate length of + * @param {ReadonlyQuat2} a dual quat to calculate length of * @returns {Number} length of a * @function */ @@ -9754,7 +9188,7 @@ var len = length; /** * Calculates the squared length of a dual quat * - * @param {quat2} a dual quat to calculate squared length of + * @param {ReadonlyQuat2} a dual quat to calculate squared length of * @returns {Number} squared length of a * @function */ @@ -9772,7 +9206,7 @@ var sqrLen = squaredLength; * Normalize a dual quat * * @param {quat2} out the receiving dual quaternion - * @param {quat2} a dual quaternion to normalize + * @param {ReadonlyQuat2} a dual quaternion to normalize * @returns {quat2} out * @function */ @@ -9808,19 +9242,19 @@ function normalize(out, a) { /** * Returns a string representation of a dual quatenion * - * @param {quat2} a dual quaternion to represent as a string + * @param {ReadonlyQuat2} a dual quaternion to represent as a string * @returns {String} string representation of the dual quat */ function str(a) { - return 'quat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ')'; + return "quat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ")"; } /** * Returns whether or not the dual quaternions have exactly the same elements in the same position (when compared with ===) * - * @param {quat2} a the first dual quaternion. - * @param {quat2} b the second dual quaternion. + * @param {ReadonlyQuat2} a the first dual quaternion. + * @param {ReadonlyQuat2} b the second dual quaternion. * @returns {Boolean} true if the dual quaternions are equal, false otherwise. */ @@ -9831,8 +9265,8 @@ function exactEquals(a, b) { /** * Returns whether or not the dual quaternions have approximately the same elements in the same position. * - * @param {quat2} a the first dual quat. - * @param {quat2} b the second dual quat. + * @param {ReadonlyQuat2} a the first dual quat. + * @param {ReadonlyQuat2} b the second dual quat. * @returns {Boolean} true if the dual quats are equal, false otherwise. */ @@ -9856,9 +9290,11 @@ function equals(a, b) { b7 = b[7]; return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)); } -},{"./common.js":22,"./mat4.js":27,"./quat.js":28}],30:[function(require,module,exports){ +},{"./common.js":21,"./mat4.js":26,"./quat.js":27}],29:[function(require,module,exports){ "use strict"; +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + Object.defineProperty(exports, "__esModule", { value: true }); @@ -9903,7 +9339,9 @@ exports.forEach = exports.sqrLen = exports.sqrDist = exports.dist = exports.div var glMatrix = _interopRequireWildcard(require("./common.js")); -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } } +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 2 Dimensional Vector @@ -9928,7 +9366,7 @@ function create() { /** * Creates a new vec2 initialized with values from an existing vector * - * @param {vec2} a vector to clone + * @param {ReadonlyVec2} a vector to clone * @returns {vec2} a new 2D vector */ @@ -9958,7 +9396,7 @@ function fromValues(x, y) { * Copy the values from one vec2 to another * * @param {vec2} out the receiving vector - * @param {vec2} a the source vector + * @param {ReadonlyVec2} a the source vector * @returns {vec2} out */ @@ -9987,8 +9425,8 @@ function set(out, x, y) { * Adds two vec2's * * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ @@ -10002,8 +9440,8 @@ function add(out, a, b) { * Subtracts vector b from vector a * * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ @@ -10017,8 +9455,8 @@ function subtract(out, a, b) { * Multiplies two vec2's * * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ @@ -10032,8 +9470,8 @@ function multiply(out, a, b) { * Divides two vec2's * * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ @@ -10047,7 +9485,7 @@ function divide(out, a, b) { * Math.ceil the components of a vec2 * * @param {vec2} out the receiving vector - * @param {vec2} a vector to ceil + * @param {ReadonlyVec2} a vector to ceil * @returns {vec2} out */ @@ -10061,7 +9499,7 @@ function ceil(out, a) { * Math.floor the components of a vec2 * * @param {vec2} out the receiving vector - * @param {vec2} a vector to floor + * @param {ReadonlyVec2} a vector to floor * @returns {vec2} out */ @@ -10075,8 +9513,8 @@ function floor(out, a) { * Returns the minimum of two vec2's * * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ @@ -10090,8 +9528,8 @@ function min(out, a, b) { * Returns the maximum of two vec2's * * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @returns {vec2} out */ @@ -10105,7 +9543,7 @@ function max(out, a, b) { * Math.round the components of a vec2 * * @param {vec2} out the receiving vector - * @param {vec2} a vector to round + * @param {ReadonlyVec2} a vector to round * @returns {vec2} out */ @@ -10119,7 +9557,7 @@ function round(out, a) { * Scales a vec2 by a scalar number * * @param {vec2} out the receiving vector - * @param {vec2} a the vector to scale + * @param {ReadonlyVec2} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {vec2} out */ @@ -10134,8 +9572,8 @@ function scale(out, a, b) { * Adds two vec2's after scaling the second operand by a scalar value * * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @param {Number} scale the amount to scale b by before adding * @returns {vec2} out */ @@ -10149,8 +9587,8 @@ function scaleAndAdd(out, a, b, scale) { /** * Calculates the euclidian distance between two vec2's * - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @returns {Number} distance between a and b */ @@ -10163,8 +9601,8 @@ function distance(a, b) { /** * Calculates the squared euclidian distance between two vec2's * - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @returns {Number} squared distance between a and b */ @@ -10177,7 +9615,7 @@ function squaredDistance(a, b) { /** * Calculates the length of a vec2 * - * @param {vec2} a vector to calculate length of + * @param {ReadonlyVec2} a vector to calculate length of * @returns {Number} length of a */ @@ -10190,7 +9628,7 @@ function length(a) { /** * Calculates the squared length of a vec2 * - * @param {vec2} a vector to calculate squared length of + * @param {ReadonlyVec2} a vector to calculate squared length of * @returns {Number} squared length of a */ @@ -10204,7 +9642,7 @@ function squaredLength(a) { * Negates the components of a vec2 * * @param {vec2} out the receiving vector - * @param {vec2} a vector to negate + * @param {ReadonlyVec2} a vector to negate * @returns {vec2} out */ @@ -10218,7 +9656,7 @@ function negate(out, a) { * Returns the inverse of the components of a vec2 * * @param {vec2} out the receiving vector - * @param {vec2} a vector to invert + * @param {ReadonlyVec2} a vector to invert * @returns {vec2} out */ @@ -10232,7 +9670,7 @@ function inverse(out, a) { * Normalize a vec2 * * @param {vec2} out the receiving vector - * @param {vec2} a vector to normalize + * @param {ReadonlyVec2} a vector to normalize * @returns {vec2} out */ @@ -10254,8 +9692,8 @@ function normalize(out, a) { /** * Calculates the dot product of two vec2's * - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @returns {Number} dot product of a and b */ @@ -10268,8 +9706,8 @@ function dot(a, b) { * Note that the cross product must by definition produce a 3D vector * * @param {vec3} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @returns {vec3} out */ @@ -10284,8 +9722,8 @@ function cross(out, a, b) { * Performs a linear interpolation between two vec2's * * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec2} out */ @@ -10318,8 +9756,8 @@ function random(out, scale) { * Transforms the vec2 with a mat2 * * @param {vec2} out the receiving vector - * @param {vec2} a the vector to transform - * @param {mat2} m matrix to transform with + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat2} m matrix to transform with * @returns {vec2} out */ @@ -10335,8 +9773,8 @@ function transformMat2(out, a, m) { * Transforms the vec2 with a mat2d * * @param {vec2} out the receiving vector - * @param {vec2} a the vector to transform - * @param {mat2d} m matrix to transform with + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat2d} m matrix to transform with * @returns {vec2} out */ @@ -10353,8 +9791,8 @@ function transformMat2d(out, a, m) { * 3rd vector component is implicitly '1' * * @param {vec2} out the receiving vector - * @param {vec2} a the vector to transform - * @param {mat3} m matrix to transform with + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat3} m matrix to transform with * @returns {vec2} out */ @@ -10372,8 +9810,8 @@ function transformMat3(out, a, m) { * 4th vector component is implicitly '1' * * @param {vec2} out the receiving vector - * @param {vec2} a the vector to transform - * @param {mat4} m matrix to transform with + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with * @returns {vec2} out */ @@ -10388,19 +9826,19 @@ function transformMat4(out, a, m) { /** * Rotate a 2D vector * @param {vec2} out The receiving vec2 - * @param {vec2} a The vec2 point to rotate - * @param {vec2} b The origin of the rotation - * @param {Number} c The angle of rotation + * @param {ReadonlyVec2} a The vec2 point to rotate + * @param {ReadonlyVec2} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians * @returns {vec2} out */ -function rotate(out, a, b, c) { +function rotate(out, a, b, rad) { //Translate point to the origin var p0 = a[0] - b[0], p1 = a[1] - b[1], - sinC = Math.sin(c), - cosC = Math.cos(c); //perform rotation and translate to correct position + sinC = Math.sin(rad), + cosC = Math.cos(rad); //perform rotation and translate to correct position out[0] = p0 * cosC - p1 * sinC + b[0]; out[1] = p0 * sinC + p1 * cosC + b[1]; @@ -10408,8 +9846,8 @@ function rotate(out, a, b, c) { } /** * Get the angle between two 2D vectors - * @param {vec2} a The first operand - * @param {vec2} b The second operand + * @param {ReadonlyVec2} a The first operand + * @param {ReadonlyVec2} b The second operand * @returns {Number} The angle in radians */ @@ -10418,30 +9856,13 @@ function angle(a, b) { var x1 = a[0], y1 = a[1], x2 = b[0], - y2 = b[1]; - var len1 = x1 * x1 + y1 * y1; - - if (len1 > 0) { - //TODO: evaluate use of glm_invsqrt here? - len1 = 1 / Math.sqrt(len1); - } - - var len2 = x2 * x2 + y2 * y2; - - if (len2 > 0) { - //TODO: evaluate use of glm_invsqrt here? - len2 = 1 / Math.sqrt(len2); - } + y2 = b[1], + // mag is the product of the magnitudes of a and b + mag = Math.sqrt(x1 * x1 + y1 * y1) * Math.sqrt(x2 * x2 + y2 * y2), + // mag &&.. short circuits if mag == 0 + cosine = mag && (x1 * x2 + y1 * y2) / mag; // Math.min(Math.max(cosine, -1), 1) clamps the cosine between -1 and 1 - var cosine = (x1 * x2 + y1 * y2) * len1 * len2; - - if (cosine > 1.0) { - return 0; - } else if (cosine < -1.0) { - return Math.PI; - } else { - return Math.acos(cosine); - } + return Math.acos(Math.min(Math.max(cosine, -1), 1)); } /** * Set the components of a vec2 to zero @@ -10459,19 +9880,19 @@ function zero(out) { /** * Returns a string representation of a vector * - * @param {vec2} a vector to represent as a string + * @param {ReadonlyVec2} a vector to represent as a string * @returns {String} string representation of the vector */ function str(a) { - return 'vec2(' + a[0] + ', ' + a[1] + ')'; + return "vec2(" + a[0] + ", " + a[1] + ")"; } /** * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) * - * @param {vec2} a The first vector. - * @param {vec2} b The second vector. + * @param {ReadonlyVec2} a The first vector. + * @param {ReadonlyVec2} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ @@ -10482,8 +9903,8 @@ function exactEquals(a, b) { /** * Returns whether or not the vectors have approximately the same elements in the same position. * - * @param {vec2} a The first vector. - * @param {vec2} b The second vector. + * @param {ReadonlyVec2} a The first vector. + * @param {ReadonlyVec2} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ @@ -10591,9 +10012,11 @@ var forEach = function () { }(); exports.forEach = forEach; -},{"./common.js":22}],31:[function(require,module,exports){ +},{"./common.js":21}],30:[function(require,module,exports){ "use strict"; +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + Object.defineProperty(exports, "__esModule", { value: true }); @@ -10641,7 +10064,9 @@ exports.forEach = exports.sqrLen = exports.len = exports.sqrDist = exports.dist var glMatrix = _interopRequireWildcard(require("./common.js")); -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } } +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 3 Dimensional Vector @@ -10667,7 +10092,7 @@ function create() { /** * Creates a new vec3 initialized with values from an existing vector * - * @param {vec3} a vector to clone + * @param {ReadonlyVec3} a vector to clone * @returns {vec3} a new 3D vector */ @@ -10682,7 +10107,7 @@ function clone(a) { /** * Calculates the length of a vec3 * - * @param {vec3} a vector to calculate length of + * @param {ReadonlyVec3} a vector to calculate length of * @returns {Number} length of a */ @@ -10714,7 +10139,7 @@ function fromValues(x, y, z) { * Copy the values from one vec3 to another * * @param {vec3} out the receiving vector - * @param {vec3} a the source vector + * @param {ReadonlyVec3} a the source vector * @returns {vec3} out */ @@ -10746,8 +10171,8 @@ function set(out, x, y, z) { * Adds two vec3's * * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ @@ -10762,8 +10187,8 @@ function add(out, a, b) { * Subtracts vector b from vector a * * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ @@ -10778,8 +10203,8 @@ function subtract(out, a, b) { * Multiplies two vec3's * * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ @@ -10794,8 +10219,8 @@ function multiply(out, a, b) { * Divides two vec3's * * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ @@ -10810,7 +10235,7 @@ function divide(out, a, b) { * Math.ceil the components of a vec3 * * @param {vec3} out the receiving vector - * @param {vec3} a vector to ceil + * @param {ReadonlyVec3} a vector to ceil * @returns {vec3} out */ @@ -10825,7 +10250,7 @@ function ceil(out, a) { * Math.floor the components of a vec3 * * @param {vec3} out the receiving vector - * @param {vec3} a vector to floor + * @param {ReadonlyVec3} a vector to floor * @returns {vec3} out */ @@ -10840,8 +10265,8 @@ function floor(out, a) { * Returns the minimum of two vec3's * * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ @@ -10856,8 +10281,8 @@ function min(out, a, b) { * Returns the maximum of two vec3's * * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ @@ -10872,7 +10297,7 @@ function max(out, a, b) { * Math.round the components of a vec3 * * @param {vec3} out the receiving vector - * @param {vec3} a vector to round + * @param {ReadonlyVec3} a vector to round * @returns {vec3} out */ @@ -10887,7 +10312,7 @@ function round(out, a) { * Scales a vec3 by a scalar number * * @param {vec3} out the receiving vector - * @param {vec3} a the vector to scale + * @param {ReadonlyVec3} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {vec3} out */ @@ -10903,8 +10328,8 @@ function scale(out, a, b) { * Adds two vec3's after scaling the second operand by a scalar value * * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @param {Number} scale the amount to scale b by before adding * @returns {vec3} out */ @@ -10919,8 +10344,8 @@ function scaleAndAdd(out, a, b, scale) { /** * Calculates the euclidian distance between two vec3's * - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @returns {Number} distance between a and b */ @@ -10934,8 +10359,8 @@ function distance(a, b) { /** * Calculates the squared euclidian distance between two vec3's * - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @returns {Number} squared distance between a and b */ @@ -10949,7 +10374,7 @@ function squaredDistance(a, b) { /** * Calculates the squared length of a vec3 * - * @param {vec3} a vector to calculate squared length of + * @param {ReadonlyVec3} a vector to calculate squared length of * @returns {Number} squared length of a */ @@ -10964,7 +10389,7 @@ function squaredLength(a) { * Negates the components of a vec3 * * @param {vec3} out the receiving vector - * @param {vec3} a vector to negate + * @param {ReadonlyVec3} a vector to negate * @returns {vec3} out */ @@ -10979,7 +10404,7 @@ function negate(out, a) { * Returns the inverse of the components of a vec3 * * @param {vec3} out the receiving vector - * @param {vec3} a vector to invert + * @param {ReadonlyVec3} a vector to invert * @returns {vec3} out */ @@ -10994,7 +10419,7 @@ function inverse(out, a) { * Normalize a vec3 * * @param {vec3} out the receiving vector - * @param {vec3} a vector to normalize + * @param {ReadonlyVec3} a vector to normalize * @returns {vec3} out */ @@ -11018,8 +10443,8 @@ function normalize(out, a) { /** * Calculates the dot product of two vec3's * - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @returns {Number} dot product of a and b */ @@ -11031,8 +10456,8 @@ function dot(a, b) { * Computes the cross product of two vec3's * * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ @@ -11053,8 +10478,8 @@ function cross(out, a, b) { * Performs a linear interpolation between two vec3's * * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec3} out */ @@ -11073,10 +10498,10 @@ function lerp(out, a, b, t) { * Performs a hermite interpolation with two control points * * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @param {vec3} c the third operand - * @param {vec3} d the fourth operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {ReadonlyVec3} c the third operand + * @param {ReadonlyVec3} d the fourth operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec3} out */ @@ -11097,10 +10522,10 @@ function hermite(out, a, b, c, d, t) { * Performs a bezier interpolation with two control points * * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @param {vec3} c the third operand - * @param {vec3} d the fourth operand + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {ReadonlyVec3} c the third operand + * @param {ReadonlyVec3} d the fourth operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec3} out */ @@ -11143,8 +10568,8 @@ function random(out, scale) { * 4th vector component is implicitly '1' * * @param {vec3} out the receiving vector - * @param {vec3} a the vector to transform - * @param {mat4} m matrix to transform with + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with * @returns {vec3} out */ @@ -11164,8 +10589,8 @@ function transformMat4(out, a, m) { * Transforms the vec3 with a mat3. * * @param {vec3} out the receiving vector - * @param {vec3} a the vector to transform - * @param {mat3} m the 3x3 matrix to transform with + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat3} m the 3x3 matrix to transform with * @returns {vec3} out */ @@ -11184,8 +10609,8 @@ function transformMat3(out, a, m) { * Can also be used for dual quaternions. (Multiply it with the real part) * * @param {vec3} out the receiving vector - * @param {vec3} a the vector to transform - * @param {quat} q quaternion to transform with + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyQuat} q quaternion to transform with * @returns {vec3} out */ @@ -11226,14 +10651,14 @@ function transformQuat(out, a, q) { /** * Rotate a 3D vector around the x-axis * @param {vec3} out The receiving vec3 - * @param {vec3} a The vec3 point to rotate - * @param {vec3} b The origin of the rotation - * @param {Number} c The angle of rotation + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians * @returns {vec3} out */ -function rotateX(out, a, b, c) { +function rotateX(out, a, b, rad) { var p = [], r = []; //Translate point to the origin @@ -11242,8 +10667,8 @@ function rotateX(out, a, b, c) { p[2] = a[2] - b[2]; //perform rotation r[0] = p[0]; - r[1] = p[1] * Math.cos(c) - p[2] * Math.sin(c); - r[2] = p[1] * Math.sin(c) + p[2] * Math.cos(c); //translate to correct position + r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad); + r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad); //translate to correct position out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; @@ -11253,14 +10678,14 @@ function rotateX(out, a, b, c) { /** * Rotate a 3D vector around the y-axis * @param {vec3} out The receiving vec3 - * @param {vec3} a The vec3 point to rotate - * @param {vec3} b The origin of the rotation - * @param {Number} c The angle of rotation + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians * @returns {vec3} out */ -function rotateY(out, a, b, c) { +function rotateY(out, a, b, rad) { var p = [], r = []; //Translate point to the origin @@ -11268,9 +10693,9 @@ function rotateY(out, a, b, c) { p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; //perform rotation - r[0] = p[2] * Math.sin(c) + p[0] * Math.cos(c); + r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad); r[1] = p[1]; - r[2] = p[2] * Math.cos(c) - p[0] * Math.sin(c); //translate to correct position + r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad); //translate to correct position out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; @@ -11280,14 +10705,14 @@ function rotateY(out, a, b, c) { /** * Rotate a 3D vector around the z-axis * @param {vec3} out The receiving vec3 - * @param {vec3} a The vec3 point to rotate - * @param {vec3} b The origin of the rotation - * @param {Number} c The angle of rotation + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians * @returns {vec3} out */ -function rotateZ(out, a, b, c) { +function rotateZ(out, a, b, rad) { var p = [], r = []; //Translate point to the origin @@ -11295,8 +10720,8 @@ function rotateZ(out, a, b, c) { p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; //perform rotation - r[0] = p[0] * Math.cos(c) - p[1] * Math.sin(c); - r[1] = p[0] * Math.sin(c) + p[1] * Math.cos(c); + r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad); + r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad); r[2] = p[2]; //translate to correct position out[0] = r[0] + b[0]; @@ -11306,26 +10731,24 @@ function rotateZ(out, a, b, c) { } /** * Get the angle between two 3D vectors - * @param {vec3} a The first operand - * @param {vec3} b The second operand + * @param {ReadonlyVec3} a The first operand + * @param {ReadonlyVec3} b The second operand * @returns {Number} The angle in radians */ function angle(a, b) { - var tempA = fromValues(a[0], a[1], a[2]); - var tempB = fromValues(b[0], b[1], b[2]); - normalize(tempA, tempA); - normalize(tempB, tempB); - var cosine = dot(tempA, tempB); - - if (cosine > 1.0) { - return 0; - } else if (cosine < -1.0) { - return Math.PI; - } else { - return Math.acos(cosine); - } + var ax = a[0], + ay = a[1], + az = a[2], + bx = b[0], + by = b[1], + bz = b[2], + mag1 = Math.sqrt(ax * ax + ay * ay + az * az), + mag2 = Math.sqrt(bx * bx + by * by + bz * bz), + mag = mag1 * mag2, + cosine = mag && dot(a, b) / mag; + return Math.acos(Math.min(Math.max(cosine, -1), 1)); } /** * Set the components of a vec3 to zero @@ -11344,19 +10767,19 @@ function zero(out) { /** * Returns a string representation of a vector * - * @param {vec3} a vector to represent as a string + * @param {ReadonlyVec3} a vector to represent as a string * @returns {String} string representation of the vector */ function str(a) { - return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')'; + return "vec3(" + a[0] + ", " + a[1] + ", " + a[2] + ")"; } /** * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) * - * @param {vec3} a The first vector. - * @param {vec3} b The second vector. + * @param {ReadonlyVec3} a The first vector. + * @param {ReadonlyVec3} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ @@ -11367,8 +10790,8 @@ function exactEquals(a, b) { /** * Returns whether or not the vectors have approximately the same elements in the same position. * - * @param {vec3} a The first vector. - * @param {vec3} b The second vector. + * @param {ReadonlyVec3} a The first vector. + * @param {ReadonlyVec3} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ @@ -11480,9 +10903,11 @@ var forEach = function () { }(); exports.forEach = forEach; -},{"./common.js":22}],32:[function(require,module,exports){ +},{"./common.js":21}],31:[function(require,module,exports){ "use strict"; +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + Object.defineProperty(exports, "__esModule", { value: true }); @@ -11523,7 +10948,9 @@ exports.forEach = exports.sqrLen = exports.len = exports.sqrDist = exports.dist var glMatrix = _interopRequireWildcard(require("./common.js")); -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } } +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * 4 Dimensional Vector @@ -11550,7 +10977,7 @@ function create() { /** * Creates a new vec4 initialized with values from an existing vector * - * @param {vec4} a vector to clone + * @param {ReadonlyVec4} a vector to clone * @returns {vec4} a new 4D vector */ @@ -11586,7 +11013,7 @@ function fromValues(x, y, z, w) { * Copy the values from one vec4 to another * * @param {vec4} out the receiving vector - * @param {vec4} a the source vector + * @param {ReadonlyVec4} a the source vector * @returns {vec4} out */ @@ -11621,8 +11048,8 @@ function set(out, x, y, z, w) { * Adds two vec4's * * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ @@ -11638,8 +11065,8 @@ function add(out, a, b) { * Subtracts vector b from vector a * * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ @@ -11655,8 +11082,8 @@ function subtract(out, a, b) { * Multiplies two vec4's * * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ @@ -11672,8 +11099,8 @@ function multiply(out, a, b) { * Divides two vec4's * * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ @@ -11689,7 +11116,7 @@ function divide(out, a, b) { * Math.ceil the components of a vec4 * * @param {vec4} out the receiving vector - * @param {vec4} a vector to ceil + * @param {ReadonlyVec4} a vector to ceil * @returns {vec4} out */ @@ -11705,7 +11132,7 @@ function ceil(out, a) { * Math.floor the components of a vec4 * * @param {vec4} out the receiving vector - * @param {vec4} a vector to floor + * @param {ReadonlyVec4} a vector to floor * @returns {vec4} out */ @@ -11721,8 +11148,8 @@ function floor(out, a) { * Returns the minimum of two vec4's * * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ @@ -11738,8 +11165,8 @@ function min(out, a, b) { * Returns the maximum of two vec4's * * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand * @returns {vec4} out */ @@ -11755,7 +11182,7 @@ function max(out, a, b) { * Math.round the components of a vec4 * * @param {vec4} out the receiving vector - * @param {vec4} a vector to round + * @param {ReadonlyVec4} a vector to round * @returns {vec4} out */ @@ -11771,7 +11198,7 @@ function round(out, a) { * Scales a vec4 by a scalar number * * @param {vec4} out the receiving vector - * @param {vec4} a the vector to scale + * @param {ReadonlyVec4} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {vec4} out */ @@ -11788,8 +11215,8 @@ function scale(out, a, b) { * Adds two vec4's after scaling the second operand by a scalar value * * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand * @param {Number} scale the amount to scale b by before adding * @returns {vec4} out */ @@ -11805,8 +11232,8 @@ function scaleAndAdd(out, a, b, scale) { /** * Calculates the euclidian distance between two vec4's * - * @param {vec4} a the first operand - * @param {vec4} b the second operand + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand * @returns {Number} distance between a and b */ @@ -11821,8 +11248,8 @@ function distance(a, b) { /** * Calculates the squared euclidian distance between two vec4's * - * @param {vec4} a the first operand - * @param {vec4} b the second operand + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand * @returns {Number} squared distance between a and b */ @@ -11837,7 +11264,7 @@ function squaredDistance(a, b) { /** * Calculates the length of a vec4 * - * @param {vec4} a vector to calculate length of + * @param {ReadonlyVec4} a vector to calculate length of * @returns {Number} length of a */ @@ -11852,7 +11279,7 @@ function length(a) { /** * Calculates the squared length of a vec4 * - * @param {vec4} a vector to calculate squared length of + * @param {ReadonlyVec4} a vector to calculate squared length of * @returns {Number} squared length of a */ @@ -11868,7 +11295,7 @@ function squaredLength(a) { * Negates the components of a vec4 * * @param {vec4} out the receiving vector - * @param {vec4} a vector to negate + * @param {ReadonlyVec4} a vector to negate * @returns {vec4} out */ @@ -11884,7 +11311,7 @@ function negate(out, a) { * Returns the inverse of the components of a vec4 * * @param {vec4} out the receiving vector - * @param {vec4} a vector to invert + * @param {ReadonlyVec4} a vector to invert * @returns {vec4} out */ @@ -11900,7 +11327,7 @@ function inverse(out, a) { * Normalize a vec4 * * @param {vec4} out the receiving vector - * @param {vec4} a vector to normalize + * @param {ReadonlyVec4} a vector to normalize * @returns {vec4} out */ @@ -11925,8 +11352,8 @@ function normalize(out, a) { /** * Calculates the dot product of two vec4's * - * @param {vec4} a the first operand - * @param {vec4} b the second operand + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand * @returns {Number} dot product of a and b */ @@ -11937,10 +11364,10 @@ function dot(a, b) { /** * Returns the cross-product of three vectors in a 4-dimensional space * - * @param {vec4} result the receiving vector - * @param {vec4} U the first vector - * @param {vec4} V the second vector - * @param {vec4} W the third vector + * @param {ReadonlyVec4} result the receiving vector + * @param {ReadonlyVec4} U the first vector + * @param {ReadonlyVec4} V the second vector + * @param {ReadonlyVec4} W the third vector * @returns {vec4} result */ @@ -11962,18 +11389,17 @@ function cross(out, u, v, w) { out[3] = -(G * D) + H * B - I * A; return out; } - -; /** * Performs a linear interpolation between two vec4's * * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec4} out */ + function lerp(out, a, b, t) { var ax = a[0]; var ay = a[1]; @@ -12025,8 +11451,8 @@ function random(out, scale) { * Transforms the vec4 with a mat4. * * @param {vec4} out the receiving vector - * @param {vec4} a the vector to transform - * @param {mat4} m matrix to transform with + * @param {ReadonlyVec4} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with * @returns {vec4} out */ @@ -12046,8 +11472,8 @@ function transformMat4(out, a, m) { * Transforms the vec4 with a quat * * @param {vec4} out the receiving vector - * @param {vec4} a the vector to transform - * @param {quat} q quaternion to transform with + * @param {ReadonlyVec4} a the vector to transform + * @param {ReadonlyQuat} q quaternion to transform with * @returns {vec4} out */ @@ -12090,19 +11516,19 @@ function zero(out) { /** * Returns a string representation of a vector * - * @param {vec4} a vector to represent as a string + * @param {ReadonlyVec4} a vector to represent as a string * @returns {String} string representation of the vector */ function str(a) { - return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; + return "vec4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; } /** * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) * - * @param {vec4} a The first vector. - * @param {vec4} b The second vector. + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ @@ -12113,8 +11539,8 @@ function exactEquals(a, b) { /** * Returns whether or not the vectors have approximately the same elements in the same position. * - * @param {vec4} a The first vector. - * @param {vec4} b The second vector. + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ @@ -12230,7 +11656,7 @@ var forEach = function () { }(); exports.forEach = forEach; -},{"./common.js":22}],33:[function(require,module,exports){ +},{"./common.js":21}],32:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; @@ -12416,1713 +11842,17 @@ process.chdir = function (dir) { }; process.umask = function() { return 0; }; -},{}],34:[function(require,module,exports){ -(function (global){ -// Underscore.js 1.9.1 -// http://underscorejs.org -// (c) 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -(function() { - - // Baseline setup - // -------------- - - // Establish the root object, `window` (`self`) in the browser, `global` - // on the server, or `this` in some virtual machines. We use `self` - // instead of `window` for `WebWorker` support. - var root = typeof self == 'object' && self.self === self && self || - typeof global == 'object' && global.global === global && global || - this || - {}; - - // Save the previous value of the `_` variable. - var previousUnderscore = root._; - - // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype; - var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null; - - // Create quick reference variables for speed access to core prototypes. - var push = ArrayProto.push, - slice = ArrayProto.slice, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeCreate = Object.create; - - // Naked function reference for surrogate-prototype-swapping. - var Ctor = function(){}; - - // Create a safe reference to the Underscore object for use below. - var _ = function(obj) { - if (obj instanceof _) return obj; - if (!(this instanceof _)) return new _(obj); - this._wrapped = obj; - }; - - // Export the Underscore object for **Node.js**, with - // backwards-compatibility for their old module API. If we're in - // the browser, add `_` as a global object. - // (`nodeType` is checked to ensure that `module` - // and `exports` are not HTML elements.) - if (typeof exports != 'undefined' && !exports.nodeType) { - if (typeof module != 'undefined' && !module.nodeType && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root._ = _; - } - - // Current version. - _.VERSION = '1.9.1'; - - // Internal function that returns an efficient (for current engines) version - // of the passed-in callback, to be repeatedly applied in other Underscore - // functions. - var optimizeCb = function(func, context, argCount) { - if (context === void 0) return func; - switch (argCount == null ? 3 : argCount) { - case 1: return function(value) { - return func.call(context, value); - }; - // The 2-argument case is omitted because we’re not using it. - case 3: return function(value, index, collection) { - return func.call(context, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(context, accumulator, value, index, collection); - }; - } - return function() { - return func.apply(context, arguments); - }; - }; - - var builtinIteratee; - - // An internal function to generate callbacks that can be applied to each - // element in a collection, returning the desired result — either `identity`, - // an arbitrary callback, a property matcher, or a property accessor. - var cb = function(value, context, argCount) { - if (_.iteratee !== builtinIteratee) return _.iteratee(value, context); - if (value == null) return _.identity; - if (_.isFunction(value)) return optimizeCb(value, context, argCount); - if (_.isObject(value) && !_.isArray(value)) return _.matcher(value); - return _.property(value); - }; - - // External wrapper for our callback generator. Users may customize - // `_.iteratee` if they want additional predicate/iteratee shorthand styles. - // This abstraction hides the internal-only argCount argument. - _.iteratee = builtinIteratee = function(value, context) { - return cb(value, context, Infinity); - }; - - // Some functions take a variable number of arguments, or a few expected - // arguments at the beginning and then a variable number of values to operate - // on. This helper accumulates all remaining arguments past the function’s - // argument length (or an explicit `startIndex`), into an array that becomes - // the last argument. Similar to ES6’s "rest parameter". - var restArguments = function(func, startIndex) { - startIndex = startIndex == null ? func.length - 1 : +startIndex; - return function() { - var length = Math.max(arguments.length - startIndex, 0), - rest = Array(length), - index = 0; - for (; index < length; index++) { - rest[index] = arguments[index + startIndex]; - } - switch (startIndex) { - case 0: return func.call(this, rest); - case 1: return func.call(this, arguments[0], rest); - case 2: return func.call(this, arguments[0], arguments[1], rest); - } - var args = Array(startIndex + 1); - for (index = 0; index < startIndex; index++) { - args[index] = arguments[index]; - } - args[startIndex] = rest; - return func.apply(this, args); - }; - }; - - // An internal function for creating a new object that inherits from another. - var baseCreate = function(prototype) { - if (!_.isObject(prototype)) return {}; - if (nativeCreate) return nativeCreate(prototype); - Ctor.prototype = prototype; - var result = new Ctor; - Ctor.prototype = null; - return result; - }; - - var shallowProperty = function(key) { - return function(obj) { - return obj == null ? void 0 : obj[key]; - }; - }; - - var has = function(obj, path) { - return obj != null && hasOwnProperty.call(obj, path); - } - - var deepGet = function(obj, path) { - var length = path.length; - for (var i = 0; i < length; i++) { - if (obj == null) return void 0; - obj = obj[path[i]]; - } - return length ? obj : void 0; - }; - - // Helper for collection methods to determine whether a collection - // should be iterated as an array or as an object. - // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength - // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 - var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; - var getLength = shallowProperty('length'); - var isArrayLike = function(collection) { - var length = getLength(collection); - return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; - }; - - // Collection Functions - // -------------------- - - // The cornerstone, an `each` implementation, aka `forEach`. - // Handles raw objects in addition to array-likes. Treats all - // sparse array-likes as if they were dense. - _.each = _.forEach = function(obj, iteratee, context) { - iteratee = optimizeCb(iteratee, context); - var i, length; - if (isArrayLike(obj)) { - for (i = 0, length = obj.length; i < length; i++) { - iteratee(obj[i], i, obj); - } - } else { - var keys = _.keys(obj); - for (i = 0, length = keys.length; i < length; i++) { - iteratee(obj[keys[i]], keys[i], obj); - } - } - return obj; - }; - - // Return the results of applying the iteratee to each element. - _.map = _.collect = function(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length, - results = Array(length); - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - results[index] = iteratee(obj[currentKey], currentKey, obj); - } - return results; - }; - - // Create a reducing function iterating left or right. - var createReduce = function(dir) { - // Wrap code that reassigns argument variables in a separate function than - // the one that accesses `arguments.length` to avoid a perf hit. (#1991) - var reducer = function(obj, iteratee, memo, initial) { - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length, - index = dir > 0 ? 0 : length - 1; - if (!initial) { - memo = obj[keys ? keys[index] : index]; - index += dir; - } - for (; index >= 0 && index < length; index += dir) { - var currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; - - return function(obj, iteratee, memo, context) { - var initial = arguments.length >= 3; - return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial); - }; - }; - - // **Reduce** builds up a single result from a list of values, aka `inject`, - // or `foldl`. - _.reduce = _.foldl = _.inject = createReduce(1); - - // The right-associative version of reduce, also known as `foldr`. - _.reduceRight = _.foldr = createReduce(-1); - - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, predicate, context) { - var keyFinder = isArrayLike(obj) ? _.findIndex : _.findKey; - var key = keyFinder(obj, predicate, context); - if (key !== void 0 && key !== -1) return obj[key]; - }; - - // Return all the elements that pass a truth test. - // Aliased as `select`. - _.filter = _.select = function(obj, predicate, context) { - var results = []; - predicate = cb(predicate, context); - _.each(obj, function(value, index, list) { - if (predicate(value, index, list)) results.push(value); - }); - return results; - }; - - // Return all the elements for which a truth test fails. - _.reject = function(obj, predicate, context) { - return _.filter(obj, _.negate(cb(predicate)), context); - }; - - // Determine whether all of the elements match a truth test. - // Aliased as `all`. - _.every = _.all = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - if (!predicate(obj[currentKey], currentKey, obj)) return false; - } - return true; - }; - - // Determine if at least one element in the object matches a truth test. - // Aliased as `any`. - _.some = _.any = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - if (predicate(obj[currentKey], currentKey, obj)) return true; - } - return false; - }; - - // Determine if the array or object contains a given item (using `===`). - // Aliased as `includes` and `include`. - _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { - if (!isArrayLike(obj)) obj = _.values(obj); - if (typeof fromIndex != 'number' || guard) fromIndex = 0; - return _.indexOf(obj, item, fromIndex) >= 0; - }; - - // Invoke a method (with arguments) on every item in a collection. - _.invoke = restArguments(function(obj, path, args) { - var contextPath, func; - if (_.isFunction(path)) { - func = path; - } else if (_.isArray(path)) { - contextPath = path.slice(0, -1); - path = path[path.length - 1]; - } - return _.map(obj, function(context) { - var method = func; - if (!method) { - if (contextPath && contextPath.length) { - context = deepGet(context, contextPath); - } - if (context == null) return void 0; - method = context[path]; - } - return method == null ? method : method.apply(context, args); - }); - }); - - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, _.property(key)); - }; - - // Convenience version of a common use case of `filter`: selecting only objects - // containing specific `key:value` pairs. - _.where = function(obj, attrs) { - return _.filter(obj, _.matcher(attrs)); - }; - - // Convenience version of a common use case of `find`: getting the first object - // containing specific `key:value` pairs. - _.findWhere = function(obj, attrs) { - return _.find(obj, _.matcher(attrs)); - }; - - // Return the maximum element (or element-based computation). - _.max = function(obj, iteratee, context) { - var result = -Infinity, lastComputed = -Infinity, - value, computed; - if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) { - obj = isArrayLike(obj) ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value > result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - _.each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed > lastComputed || computed === -Infinity && result === -Infinity) { - result = v; - lastComputed = computed; - } - }); - } - return result; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iteratee, context) { - var result = Infinity, lastComputed = Infinity, - value, computed; - if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) { - obj = isArrayLike(obj) ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value < result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - _.each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed < lastComputed || computed === Infinity && result === Infinity) { - result = v; - lastComputed = computed; - } - }); - } - return result; - }; - - // Shuffle a collection. - _.shuffle = function(obj) { - return _.sample(obj, Infinity); - }; - - // Sample **n** random values from a collection using the modern version of the - // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). - // If **n** is not specified, returns a single random element. - // The internal `guard` argument allows it to work with `map`. - _.sample = function(obj, n, guard) { - if (n == null || guard) { - if (!isArrayLike(obj)) obj = _.values(obj); - return obj[_.random(obj.length - 1)]; - } - var sample = isArrayLike(obj) ? _.clone(obj) : _.values(obj); - var length = getLength(sample); - n = Math.max(Math.min(n, length), 0); - var last = length - 1; - for (var index = 0; index < n; index++) { - var rand = _.random(index, last); - var temp = sample[index]; - sample[index] = sample[rand]; - sample[rand] = temp; - } - return sample.slice(0, n); - }; - - // Sort the object's values by a criterion produced by an iteratee. - _.sortBy = function(obj, iteratee, context) { - var index = 0; - iteratee = cb(iteratee, context); - return _.pluck(_.map(obj, function(value, key, list) { - return { - value: value, - index: index++, - criteria: iteratee(value, key, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index - right.index; - }), 'value'); - }; - - // An internal function used for aggregate "group by" operations. - var group = function(behavior, partition) { - return function(obj, iteratee, context) { - var result = partition ? [[], []] : {}; - iteratee = cb(iteratee, context); - _.each(obj, function(value, index) { - var key = iteratee(value, index, obj); - behavior(result, value, key); - }); - return result; - }; - }; - - // Groups the object's values by a criterion. Pass either a string attribute - // to group by, or a function that returns the criterion. - _.groupBy = group(function(result, value, key) { - if (has(result, key)) result[key].push(value); else result[key] = [value]; - }); - - // Indexes the object's values by a criterion, similar to `groupBy`, but for - // when you know that your index values will be unique. - _.indexBy = group(function(result, value, key) { - result[key] = value; - }); - - // Counts instances of an object that group by a certain criterion. Pass - // either a string attribute to count by, or a function that returns the - // criterion. - _.countBy = group(function(result, value, key) { - if (has(result, key)) result[key]++; else result[key] = 1; - }); - - var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; - // Safely create a real, live array from anything iterable. - _.toArray = function(obj) { - if (!obj) return []; - if (_.isArray(obj)) return slice.call(obj); - if (_.isString(obj)) { - // Keep surrogate pair characters together - return obj.match(reStrSymbol); - } - if (isArrayLike(obj)) return _.map(obj, _.identity); - return _.values(obj); - }; - - // Return the number of elements in an object. - _.size = function(obj) { - if (obj == null) return 0; - return isArrayLike(obj) ? obj.length : _.keys(obj).length; - }; - - // Split a collection into two arrays: one whose elements all satisfy the given - // predicate, and one whose elements all do not satisfy the predicate. - _.partition = group(function(result, value, pass) { - result[pass ? 0 : 1].push(value); - }, true); - - // Array Functions - // --------------- - - // Get the first element of an array. Passing **n** will return the first N - // values in the array. Aliased as `head` and `take`. The **guard** check - // allows it to work with `_.map`. - _.first = _.head = _.take = function(array, n, guard) { - if (array == null || array.length < 1) return n == null ? void 0 : []; - if (n == null || guard) return array[0]; - return _.initial(array, array.length - n); - }; - - // Returns everything but the last entry of the array. Especially useful on - // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. - _.initial = function(array, n, guard) { - return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); - }; - - // Get the last element of an array. Passing **n** will return the last N - // values in the array. - _.last = function(array, n, guard) { - if (array == null || array.length < 1) return n == null ? void 0 : []; - if (n == null || guard) return array[array.length - 1]; - return _.rest(array, Math.max(0, array.length - n)); - }; - - // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. - // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. - _.rest = _.tail = _.drop = function(array, n, guard) { - return slice.call(array, n == null || guard ? 1 : n); - }; - - // Trim out all falsy values from an array. - _.compact = function(array) { - return _.filter(array, Boolean); - }; - - // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, strict, output) { - output = output || []; - var idx = output.length; - for (var i = 0, length = getLength(input); i < length; i++) { - var value = input[i]; - if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { - // Flatten current level of array or arguments object. - if (shallow) { - var j = 0, len = value.length; - while (j < len) output[idx++] = value[j++]; - } else { - flatten(value, shallow, strict, output); - idx = output.length; - } - } else if (!strict) { - output[idx++] = value; - } - } - return output; - }; - - // Flatten out an array, either recursively (by default), or just one level. - _.flatten = function(array, shallow) { - return flatten(array, shallow, false); - }; - - // Return a version of the array that does not contain the specified value(s). - _.without = restArguments(function(array, otherArrays) { - return _.difference(array, otherArrays); - }); - - // Produce a duplicate-free version of the array. If the array has already - // been sorted, you have the option of using a faster algorithm. - // The faster algorithm will not work with an iteratee if the iteratee - // is not a one-to-one function, so providing an iteratee will disable - // the faster algorithm. - // Aliased as `unique`. - _.uniq = _.unique = function(array, isSorted, iteratee, context) { - if (!_.isBoolean(isSorted)) { - context = iteratee; - iteratee = isSorted; - isSorted = false; - } - if (iteratee != null) iteratee = cb(iteratee, context); - var result = []; - var seen = []; - for (var i = 0, length = getLength(array); i < length; i++) { - var value = array[i], - computed = iteratee ? iteratee(value, i, array) : value; - if (isSorted && !iteratee) { - if (!i || seen !== computed) result.push(value); - seen = computed; - } else if (iteratee) { - if (!_.contains(seen, computed)) { - seen.push(computed); - result.push(value); - } - } else if (!_.contains(result, value)) { - result.push(value); - } - } - return result; - }; - - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = restArguments(function(arrays) { - return _.uniq(flatten(arrays, true, true)); - }); - - // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersection = function(array) { - var result = []; - var argsLength = arguments.length; - for (var i = 0, length = getLength(array); i < length; i++) { - var item = array[i]; - if (_.contains(result, item)) continue; - var j; - for (j = 1; j < argsLength; j++) { - if (!_.contains(arguments[j], item)) break; - } - if (j === argsLength) result.push(item); - } - return result; - }; - - // Take the difference between one array and a number of other arrays. - // Only the elements present in just the first array will remain. - _.difference = restArguments(function(array, rest) { - rest = flatten(rest, true, true); - return _.filter(array, function(value){ - return !_.contains(rest, value); - }); - }); - - // Complement of _.zip. Unzip accepts an array of arrays and groups - // each array's elements on shared indices. - _.unzip = function(array) { - var length = array && _.max(array, getLength).length || 0; - var result = Array(length); - - for (var index = 0; index < length; index++) { - result[index] = _.pluck(array, index); - } - return result; - }; - - // Zip together multiple lists into a single array -- elements that share - // an index go together. - _.zip = restArguments(_.unzip); - - // Converts lists into objects. Pass either a single array of `[key, value]` - // pairs, or two parallel arrays of the same length -- one of keys, and one of - // the corresponding values. Passing by pairs is the reverse of _.pairs. - _.object = function(list, values) { - var result = {}; - for (var i = 0, length = getLength(list); i < length; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; - }; - - // Generator function to create the findIndex and findLastIndex functions. - var createPredicateIndexFinder = function(dir) { - return function(array, predicate, context) { - predicate = cb(predicate, context); - var length = getLength(array); - var index = dir > 0 ? 0 : length - 1; - for (; index >= 0 && index < length; index += dir) { - if (predicate(array[index], index, array)) return index; - } - return -1; - }; - }; - - // Returns the first index on an array-like that passes a predicate test. - _.findIndex = createPredicateIndexFinder(1); - _.findLastIndex = createPredicateIndexFinder(-1); - - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iteratee, context) { - iteratee = cb(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = getLength(array); - while (low < high) { - var mid = Math.floor((low + high) / 2); - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; - }; - - // Generator function to create the indexOf and lastIndexOf functions. - var createIndexFinder = function(dir, predicateFind, sortedIndex) { - return function(array, item, idx) { - var i = 0, length = getLength(array); - if (typeof idx == 'number') { - if (dir > 0) { - i = idx >= 0 ? idx : Math.max(idx + length, i); - } else { - length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; - } - } else if (sortedIndex && idx && length) { - idx = sortedIndex(array, item); - return array[idx] === item ? idx : -1; - } - if (item !== item) { - idx = predicateFind(slice.call(array, i, length), _.isNaN); - return idx >= 0 ? idx + i : -1; - } - for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { - if (array[idx] === item) return idx; - } - return -1; - }; - }; - - // Return the position of the first occurrence of an item in an array, - // or -1 if the item is not included in the array. - // If the array is large and already in sort order, pass `true` - // for **isSorted** to use binary search. - _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); - _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); - - // Generate an integer Array containing an arithmetic progression. A port of - // the native Python `range()` function. See - // [the Python documentation](http://docs.python.org/library/functions.html#range). - _.range = function(start, stop, step) { - if (stop == null) { - stop = start || 0; - start = 0; - } - if (!step) { - step = stop < start ? -1 : 1; - } - - var length = Math.max(Math.ceil((stop - start) / step), 0); - var range = Array(length); - - for (var idx = 0; idx < length; idx++, start += step) { - range[idx] = start; - } - - return range; - }; - - // Chunk a single array into multiple arrays, each containing `count` or fewer - // items. - _.chunk = function(array, count) { - if (count == null || count < 1) return []; - var result = []; - var i = 0, length = array.length; - while (i < length) { - result.push(slice.call(array, i, i += count)); - } - return result; - }; - - // Function (ahem) Functions - // ------------------ - - // Determines whether to execute a function as a constructor - // or a normal function with the provided arguments. - var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { - if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); - var self = baseCreate(sourceFunc.prototype); - var result = sourceFunc.apply(self, args); - if (_.isObject(result)) return result; - return self; - }; - - // Create a function bound to a given object (assigning `this`, and arguments, - // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if - // available. - _.bind = restArguments(function(func, context, args) { - if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); - var bound = restArguments(function(callArgs) { - return executeBound(func, bound, context, this, args.concat(callArgs)); - }); - return bound; - }); - - // Partially apply a function by creating a version that has had some of its - // arguments pre-filled, without changing its dynamic `this` context. _ acts - // as a placeholder by default, allowing any combination of arguments to be - // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument. - _.partial = restArguments(function(func, boundArgs) { - var placeholder = _.partial.placeholder; - var bound = function() { - var position = 0, length = boundArgs.length; - var args = Array(length); - for (var i = 0; i < length; i++) { - args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i]; - } - while (position < arguments.length) args.push(arguments[position++]); - return executeBound(func, bound, this, this, args); - }; - return bound; - }); - - _.partial.placeholder = _; - - // Bind a number of an object's methods to that object. Remaining arguments - // are the method names to be bound. Useful for ensuring that all callbacks - // defined on an object belong to it. - _.bindAll = restArguments(function(obj, keys) { - keys = flatten(keys, false, false); - var index = keys.length; - if (index < 1) throw new Error('bindAll must be passed function names'); - while (index--) { - var key = keys[index]; - obj[key] = _.bind(obj[key], obj); - } - }); - - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memoize = function(key) { - var cache = memoize.cache; - var address = '' + (hasher ? hasher.apply(this, arguments) : key); - if (!has(cache, address)) cache[address] = func.apply(this, arguments); - return cache[address]; - }; - memoize.cache = {}; - return memoize; - }; - - // Delays a function for the given number of milliseconds, and then calls - // it with the arguments supplied. - _.delay = restArguments(function(func, wait, args) { - return setTimeout(function() { - return func.apply(null, args); - }, wait); - }); - - // Defers a function, scheduling it to run after the current call stack has - // cleared. - _.defer = _.partial(_.delay, _, 1); - - // Returns a function, that, when invoked, will only be triggered at most once - // during a given window of time. Normally, the throttled function will run - // as much as it can, without ever going more than once per `wait` duration; - // but if you'd like to disable the execution on the leading edge, pass - // `{leading: false}`. To disable execution on the trailing edge, ditto. - _.throttle = function(func, wait, options) { - var timeout, context, args, result; - var previous = 0; - if (!options) options = {}; - - var later = function() { - previous = options.leading === false ? 0 : _.now(); - timeout = null; - result = func.apply(context, args); - if (!timeout) context = args = null; - }; - - var throttled = function() { - var now = _.now(); - if (!previous && options.leading === false) previous = now; - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0 || remaining > wait) { - if (timeout) { - clearTimeout(timeout); - timeout = null; - } - previous = now; - result = func.apply(context, args); - if (!timeout) context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); - } - return result; - }; - - throttled.cancel = function() { - clearTimeout(timeout); - previous = 0; - timeout = context = args = null; - }; - - return throttled; - }; - - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - _.debounce = function(func, wait, immediate) { - var timeout, result; - - var later = function(context, args) { - timeout = null; - if (args) result = func.apply(context, args); - }; - - var debounced = restArguments(function(args) { - if (timeout) clearTimeout(timeout); - if (immediate) { - var callNow = !timeout; - timeout = setTimeout(later, wait); - if (callNow) result = func.apply(this, args); - } else { - timeout = _.delay(later, wait, this, args); - } - - return result; - }); - - debounced.cancel = function() { - clearTimeout(timeout); - timeout = null; - }; - - return debounced; - }; - - // Returns the first function passed as an argument to the second, - // allowing you to adjust arguments, run code before and after, and - // conditionally execute the original function. - _.wrap = function(func, wrapper) { - return _.partial(wrapper, func); - }; - - // Returns a negated version of the passed-in predicate. - _.negate = function(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; - }; - - // Returns a function that is the composition of a list of functions, each - // consuming the return value of the function that follows. - _.compose = function() { - var args = arguments; - var start = args.length - 1; - return function() { - var i = start; - var result = args[start].apply(this, arguments); - while (i--) result = args[i].call(this, result); - return result; - }; - }; - - // Returns a function that will only be executed on and after the Nth call. - _.after = function(times, func) { - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; - }; - - // Returns a function that will only be executed up to (but not including) the Nth call. - _.before = function(times, func) { - var memo; - return function() { - if (--times > 0) { - memo = func.apply(this, arguments); - } - if (times <= 1) func = null; - return memo; - }; - }; - - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = _.partial(_.before, 2); - - _.restArguments = restArguments; - - // Object Functions - // ---------------- - - // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. - var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); - var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', - 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; - - var collectNonEnumProps = function(obj, keys) { - var nonEnumIdx = nonEnumerableProps.length; - var constructor = obj.constructor; - var proto = _.isFunction(constructor) && constructor.prototype || ObjProto; - - // Constructor is a special case. - var prop = 'constructor'; - if (has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); - - while (nonEnumIdx--) { - prop = nonEnumerableProps[nonEnumIdx]; - if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { - keys.push(prop); - } - } - }; - - // Retrieve the names of an object's own properties. - // Delegates to **ECMAScript 5**'s native `Object.keys`. - _.keys = function(obj) { - if (!_.isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (has(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; - }; - - // Retrieve all the property names of an object. - _.allKeys = function(obj) { - if (!_.isObject(obj)) return []; - var keys = []; - for (var key in obj) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; - }; - - // Retrieve the values of an object's properties. - _.values = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[keys[i]]; - } - return values; - }; - - // Returns the results of applying the iteratee to each element of the object. - // In contrast to _.map it returns an object. - _.mapObject = function(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var keys = _.keys(obj), - length = keys.length, - results = {}; - for (var index = 0; index < length; index++) { - var currentKey = keys[index]; - results[currentKey] = iteratee(obj[currentKey], currentKey, obj); - } - return results; - }; - - // Convert an object into a list of `[key, value]` pairs. - // The opposite of _.object. - _.pairs = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var pairs = Array(length); - for (var i = 0; i < length; i++) { - pairs[i] = [keys[i], obj[keys[i]]]; - } - return pairs; - }; - - // Invert the keys and values of an object. The values must be serializable. - _.invert = function(obj) { - var result = {}; - var keys = _.keys(obj); - for (var i = 0, length = keys.length; i < length; i++) { - result[obj[keys[i]]] = keys[i]; - } - return result; - }; - - // Return a sorted list of the function names available on the object. - // Aliased as `methods`. - _.functions = _.methods = function(obj) { - var names = []; - for (var key in obj) { - if (_.isFunction(obj[key])) names.push(key); - } - return names.sort(); - }; - - // An internal function for creating assigner functions. - var createAssigner = function(keysFunc, defaults) { - return function(obj) { - var length = arguments.length; - if (defaults) obj = Object(obj); - if (length < 2 || obj == null) return obj; - for (var index = 1; index < length; index++) { - var source = arguments[index], - keys = keysFunc(source), - l = keys.length; - for (var i = 0; i < l; i++) { - var key = keys[i]; - if (!defaults || obj[key] === void 0) obj[key] = source[key]; - } - } - return obj; - }; - }; - - // Extend a given object with all the properties in passed-in object(s). - _.extend = createAssigner(_.allKeys); - - // Assigns a given object with all the own properties in the passed-in object(s). - // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) - _.extendOwn = _.assign = createAssigner(_.keys); - - // Returns the first key on an object that passes a predicate test. - _.findKey = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = _.keys(obj), key; - for (var i = 0, length = keys.length; i < length; i++) { - key = keys[i]; - if (predicate(obj[key], key, obj)) return key; - } - }; - - // Internal pick helper function to determine if `obj` has key `key`. - var keyInObj = function(value, key, obj) { - return key in obj; - }; - - // Return a copy of the object only containing the whitelisted properties. - _.pick = restArguments(function(obj, keys) { - var result = {}, iteratee = keys[0]; - if (obj == null) return result; - if (_.isFunction(iteratee)) { - if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]); - keys = _.allKeys(obj); - } else { - iteratee = keyInObj; - keys = flatten(keys, false, false); - obj = Object(obj); - } - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i]; - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } - return result; - }); - - // Return a copy of the object without the blacklisted properties. - _.omit = restArguments(function(obj, keys) { - var iteratee = keys[0], context; - if (_.isFunction(iteratee)) { - iteratee = _.negate(iteratee); - if (keys.length > 1) context = keys[1]; - } else { - keys = _.map(flatten(keys, false, false), String); - iteratee = function(value, key) { - return !_.contains(keys, key); - }; - } - return _.pick(obj, iteratee, context); - }); - - // Fill in a given object with default properties. - _.defaults = createAssigner(_.allKeys, true); - - // Creates an object that inherits from the given prototype object. - // If additional properties are provided then they will be added to the - // created object. - _.create = function(prototype, props) { - var result = baseCreate(prototype); - if (props) _.extendOwn(result, props); - return result; - }; - - // Create a (shallow-cloned) duplicate of an object. - _.clone = function(obj) { - if (!_.isObject(obj)) return obj; - return _.isArray(obj) ? obj.slice() : _.extend({}, obj); - }; - - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in - // order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - }; - - // Returns whether an object has a given set of `key:value` pairs. - _.isMatch = function(object, attrs) { - var keys = _.keys(attrs), length = keys.length; - if (object == null) return !length; - var obj = Object(object); - for (var i = 0; i < length; i++) { - var key = keys[i]; - if (attrs[key] !== obj[key] || !(key in obj)) return false; - } - return true; - }; - - - // Internal recursive comparison function for `isEqual`. - var eq, deepEq; - eq = function(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // `null` or `undefined` only equal to itself (strict comparison). - if (a == null || b == null) return false; - // `NaN`s are equivalent, but non-reflexive. - if (a !== a) return b !== b; - // Exhaust primitive checks - var type = typeof a; - if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; - return deepEq(a, b, aStack, bStack); - }; - - // Internal recursive comparison function for `isEqual`. - deepEq = function(a, b, aStack, bStack) { - // Unwrap any wrapped objects. - if (a instanceof _) a = a._wrapped; - if (b instanceof _) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - switch (className) { - // Strings, numbers, regular expressions, dates, and booleans are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN. - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - case '[object Symbol]': - return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); - } - - var areArrays = className === '[object Array]'; - if (!areArrays) { - if (typeof a != 'object' || typeof b != 'object') return false; - - // Objects with different constructors are not equivalent, but `Object`s or `Array`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && - _.isFunction(bCtor) && bCtor instanceof bCtor) - && ('constructor' in a && 'constructor' in b)) { - return false; - } - } - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - - // Initializing stack of traversed objects. - // It's done here since we only need them for objects and arrays comparison. - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - - // Recursively compare objects and arrays. - if (areArrays) { - // Compare array lengths to determine if a deep comparison is necessary. - length = a.length; - if (length !== b.length) return false; - // Deep compare the contents, ignoring non-numeric properties. - while (length--) { - if (!eq(a[length], b[length], aStack, bStack)) return false; - } - } else { - // Deep compare objects. - var keys = _.keys(a), key; - length = keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - if (_.keys(b).length !== length) return false; - while (length--) { - // Deep compare each member - key = keys[length]; - if (!(has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return true; - }; - - // Perform a deep comparison to check if two objects are equal. - _.isEqual = function(a, b) { - return eq(a, b); - }; - - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - _.isEmpty = function(obj) { - if (obj == null) return true; - if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; - return _.keys(obj).length === 0; - }; - - // Is a given value a DOM element? - _.isElement = function(obj) { - return !!(obj && obj.nodeType === 1); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) === '[object Array]'; - }; - - // Is a given variable an object? - _.isObject = function(obj) { - var type = typeof obj; - return type === 'function' || type === 'object' && !!obj; - }; - - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError, isMap, isWeakMap, isSet, isWeakSet. - _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], function(name) { - _['is' + name] = function(obj) { - return toString.call(obj) === '[object ' + name + ']'; - }; - }); - - // Define a fallback version of the method in browsers (ahem, IE < 9), where - // there isn't any inspectable "Arguments" type. - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return has(obj, 'callee'); - }; - } - - // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, - // IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). - var nodelist = root.document && root.document.childNodes; - if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') { - _.isFunction = function(obj) { - return typeof obj == 'function' || false; - }; - } - - // Is a given object a finite number? - _.isFinite = function(obj) { - return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj)); - }; - - // Is the given value `NaN`? - _.isNaN = function(obj) { - return _.isNumber(obj) && isNaN(obj); - }; - - // Is a given value a boolean? - _.isBoolean = function(obj) { - return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; - }; - - // Is a given value equal to null? - _.isNull = function(obj) { - return obj === null; - }; - - // Is a given variable undefined? - _.isUndefined = function(obj) { - return obj === void 0; - }; - - // Shortcut function for checking if an object has a given property directly - // on itself (in other words, not on a prototype). - _.has = function(obj, path) { - if (!_.isArray(path)) { - return has(obj, path); - } - var length = path.length; - for (var i = 0; i < length; i++) { - var key = path[i]; - if (obj == null || !hasOwnProperty.call(obj, key)) { - return false; - } - obj = obj[key]; - } - return !!length; - }; - - // Utility Functions - // ----------------- - - // Run Underscore.js in *noConflict* mode, returning the `_` variable to its - // previous owner. Returns a reference to the Underscore object. - _.noConflict = function() { - root._ = previousUnderscore; - return this; - }; - - // Keep the identity function around for default iteratees. - _.identity = function(value) { - return value; - }; - - // Predicate-generating functions. Often useful outside of Underscore. - _.constant = function(value) { - return function() { - return value; - }; - }; - - _.noop = function(){}; - - // Creates a function that, when passed an object, will traverse that object’s - // properties down the given `path`, specified as an array of keys or indexes. - _.property = function(path) { - if (!_.isArray(path)) { - return shallowProperty(path); - } - return function(obj) { - return deepGet(obj, path); - }; - }; - - // Generates a function for a given object that returns a given property. - _.propertyOf = function(obj) { - if (obj == null) { - return function(){}; - } - return function(path) { - return !_.isArray(path) ? obj[path] : deepGet(obj, path); - }; - }; - - // Returns a predicate for checking whether an object has a given set of - // `key:value` pairs. - _.matcher = _.matches = function(attrs) { - attrs = _.extendOwn({}, attrs); - return function(obj) { - return _.isMatch(obj, attrs); - }; - }; - - // Run a function **n** times. - _.times = function(n, iteratee, context) { - var accum = Array(Math.max(0, n)); - iteratee = optimizeCb(iteratee, context, 1); - for (var i = 0; i < n; i++) accum[i] = iteratee(i); - return accum; - }; - - // Return a random integer between min and max (inclusive). - _.random = function(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); - }; - - // A (possibly faster) way to get the current timestamp as an integer. - _.now = Date.now || function() { - return new Date().getTime(); - }; - - // List of HTML entities for escaping. - var escapeMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' - }; - var unescapeMap = _.invert(escapeMap); - - // Functions for escaping and unescaping strings to/from HTML interpolation. - var createEscaper = function(map) { - var escaper = function(match) { - return map[match]; - }; - // Regexes for identifying a key that needs to be escaped. - var source = '(?:' + _.keys(map).join('|') + ')'; - var testRegexp = RegExp(source); - var replaceRegexp = RegExp(source, 'g'); - return function(string) { - string = string == null ? '' : '' + string; - return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; - }; - }; - _.escape = createEscaper(escapeMap); - _.unescape = createEscaper(unescapeMap); - - // Traverses the children of `obj` along `path`. If a child is a function, it - // is invoked with its parent as context. Returns the value of the final - // child, or `fallback` if any child is undefined. - _.result = function(obj, path, fallback) { - if (!_.isArray(path)) path = [path]; - var length = path.length; - if (!length) { - return _.isFunction(fallback) ? fallback.call(obj) : fallback; - } - for (var i = 0; i < length; i++) { - var prop = obj == null ? void 0 : obj[path[i]]; - if (prop === void 0) { - prop = fallback; - i = length; // Ensure we don't continue iterating. - } - obj = _.isFunction(prop) ? prop.call(obj) : prop; - } - return obj; - }; - - // Generate a unique integer id (unique within the entire client session). - // Useful for temporary DOM ids. - var idCounter = 0; - _.uniqueId = function(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; - }; - - // By default, Underscore uses ERB-style template delimiters, change the - // following template settings to use alternative delimiters. - _.templateSettings = { - evaluate: /<%([\s\S]+?)%>/g, - interpolate: /<%=([\s\S]+?)%>/g, - escape: /<%-([\s\S]+?)%>/g - }; - - // When customizing `templateSettings`, if you don't want to define an - // interpolation, evaluation or escaping regex, we need one that is - // guaranteed not to match. - var noMatch = /(.)^/; - - // Certain characters need to be escaped so that they can be put into a - // string literal. - var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; - - var escapeChar = function(match) { - return '\\' + escapes[match]; - }; - - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - // NB: `oldSettings` only exists for backwards compatibility. - _.template = function(text, settings, oldSettings) { - if (!settings && oldSettings) settings = oldSettings; - settings = _.defaults({}, settings, _.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset).replace(escapeRegExp, escapeChar); - index = offset + match.length; - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } else if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } else if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - - // Adobe VMs need the match returned to produce the correct offset. - return match; - }); - source += "';\n"; - - // If a variable is not specified, place data values in local scope. - if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + 'return __p;\n'; - - var render; - try { - render = new Function(settings.variable || 'obj', '_', source); - } catch (e) { - e.source = source; - throw e; - } - - var template = function(data) { - return render.call(this, data, _); - }; - - // Provide the compiled source as a convenience for precompilation. - var argument = settings.variable || 'obj'; - template.source = 'function(' + argument + '){\n' + source + '}'; - - return template; - }; - - // Add a "chain" function. Start chaining a wrapped Underscore object. - _.chain = function(obj) { - var instance = _(obj); - instance._chain = true; - return instance; - }; - - // OOP - // --------------- - // If Underscore is called as a function, it returns a wrapped object that - // can be used OO-style. This wrapper holds altered versions of all the - // underscore functions. Wrapped objects may be chained. - - // Helper function to continue chaining intermediate results. - var chainResult = function(instance, obj) { - return instance._chain ? _(obj).chain() : obj; - }; - - // Add your own custom functions to the Underscore object. - _.mixin = function(obj) { - _.each(_.functions(obj), function(name) { - var func = _[name] = obj[name]; - _.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return chainResult(this, func.apply(_, args)); - }; - }); - return _; - }; - - // Add all of the Underscore functions to the wrapper object. - _.mixin(_); - - // Add all mutator Array functions to the wrapper. - _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - var obj = this._wrapped; - method.apply(obj, arguments); - if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; - return chainResult(this, obj); - }; - }); - - // Add all accessor Array functions to the wrapper. - _.each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - return chainResult(this, method.apply(this._wrapped, arguments)); - }; - }); - - // Extracts the result from a wrapped and chained object. - _.prototype.value = function() { - return this._wrapped; - }; - - // Provide unwrapping proxy for some methods used in engine operations - // such as arithmetic and JSON stringification. - _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; - - _.prototype.toString = function() { - return String(this._wrapped); - }; - - // AMD registration happens at the end for compatibility with AMD loaders - // that may not enforce next-turn semantics on modules. Even though general - // practice for AMD registration is to be anonymous, underscore registers - // as a named module because, like jQuery, it is a base library that is - // popular enough to be bundled in a third party lib, but not be part of - // an AMD load request. Those cases could generate an error when an - // anonymous define() is called outside of a loader request. - if (typeof define == 'function' && define.amd) { - define('underscore', [], function() { - return _; - }); - } -}()); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],35:[function(require,module,exports){ +},{}],33:[function(require,module,exports){ 'use strict'; -module.exports = function() { +module.exports = function () { throw new Error( 'ws does not work in the browser. Browser clients must use the native ' + 'WebSocket object' ); }; -},{}],36:[function(require,module,exports){ +},{}],34:[function(require,module,exports){ if (typeof(window) !== 'undefined' && typeof(window.requestAnimationFrame) !== 'function') { window.requestAnimationFrame = ( window.webkitRequestAnimationFrame || @@ -14135,4 +11865,4 @@ if (typeof(window) !== 'undefined' && typeof(window.requestAnimationFrame) !== ' Leap = require("../lib/index"); -},{"../lib/index":12}]},{},[36]); +},{"../lib/index":11}]},{},[34]); diff --git a/leap-1.1.0.min.js b/leap-1.1.0.min.js new file mode 100644 index 00000000..a90d2a02 --- /dev/null +++ b/leap-1.1.0.min.js @@ -0,0 +1,9 @@ +/*! + * LeapJS v1.1.0 + * http://github.com/leapmotion/leapjs/ + * + * Copyright 2020 Ultraleap, Inc. and other contributors + * Released under the Apache-2.0 license + * http://github.com/leapmotion/leapjs/blob/master/LICENSE + */ +!function r(o,i,a){function s(n,t){if(!i[n]){if(!o[n]){var e="function"==typeof require&&require;if(!t&&e)return e(n,!0);if(u)return u(n,!0);throw(e=new Error("Cannot find module '"+n+"'")).code="MODULE_NOT_FOUND",e}e=i[n]={exports:{}},o[n][0].call(e.exports,function(t){return s(o[n][1][t]||t)},e,e.exports,r,o,i,a)}return i[n].exports}for(var u="function"==typeof require&&require,t=0;t=this.size||t>=this._buf.length))return this._buf[(this.pos-t-1)%this.size]},n.prototype.push=function(t){return this._buf[this.pos%this.size]=t,this.pos++}},{}],3:[function(t,n,e){var r=t("../protocol").chooseProtocol,t=t("events").EventEmitter,o=n.exports=function(t){this.opts=Object.assign({host:"127.0.0.1",scheme:this.getScheme(),port:this.getPort(),background:!1,optimizeHMD:!1,requestProtocolVersion:o.defaultProtocolVersion},t||{}),this.host=this.opts.host,this.port=this.opts.port,this.scheme=this.opts.scheme,this.protocolVersionVerified=!1,this.background=null,this.optimizeHMD=null,this.on("ready",function(){this.setBackground(this.opts.background),this.setOptimizeHMD(this.opts.optimizeHMD),this.opts.optimizeHMD?console.log("Optimized for head mounted display usage."):console.log("Optimized for desktop usage.")})};o.defaultProtocolVersion=6,o.prototype.getUrl=function(){return this.scheme+"//"+this.host+":"+this.port+"/v"+this.opts.requestProtocolVersion+".json"},o.prototype.getScheme=function(){return"ws:"},o.prototype.getPort=function(){return 6437},o.prototype.setBackground=function(t){this.opts.background=t,this.protocol&&this.protocol.sendBackground&&this.background!==this.opts.background&&(this.background=this.opts.background,this.protocol.sendBackground(this,this.opts.background))},o.prototype.setOptimizeHMD=function(t){this.opts.optimizeHMD=t,this.protocol&&this.protocol.sendOptimizeHMD&&this.optimizeHMD!==this.opts.optimizeHMD&&(this.optimizeHMD=this.opts.optimizeHMD,this.protocol.sendOptimizeHMD(this,this.opts.optimizeHMD))},o.prototype.handleOpen=function(){this.connected||(this.connected=!0,this.emit("connect"))},o.prototype.handleClose=function(t,n){this.connected&&(this.disconnect(),1001===t&&1Upgrade",{onclick:function(t){return"leapjs-decline-upgrade"!=t.target.id&&(t=window.open(e,"_blank","height=800,width=1000,location=1,menubar=1,resizable=1,status=1,toolbar=1,scrollbars=1"),window.focus&&t.focus()),r.hide(),!0},onmousemove:function(t){t.target==document.getElementById("leapjs-decline-upgrade")?(document.getElementById("leapjs-decline-upgrade").style.color="#000",document.getElementById("leapjs-decline-upgrade").style.boxShadow="0px 0px 2px #5daa00",document.getElementById("leapjs-accept-upgrade").style.color="#444",document.getElementById("leapjs-accept-upgrade").style.boxShadow="none"):(document.getElementById("leapjs-accept-upgrade").style.color="#000",document.getElementById("leapjs-accept-upgrade").style.boxShadow="0px 0px 2px #5daa00",document.getElementById("leapjs-decline-upgrade").style.color="#444",document.getElementById("leapjs-decline-upgrade").style.boxShadow="none")},onmouseout:function(){document.getElementById("leapjs-decline-upgrade").style.color="#444",document.getElementById("leapjs-decline-upgrade").style.boxShadow="none",document.getElementById("leapjs-accept-upgrade").style.color="#444",document.getElementById("leapjs-accept-upgrade").style.boxShadow="none"}});return r.show()},o.hasWarnedBones=!1,o.warnBones=function(){this.hasWarnedBones||(this.hasWarnedBones=!0,console.warn("Your Leap Service is out of date"),void 0!==t&&t.versions&&t.versions.node||this.warnOutOfDate({reason:"bones"}))}}).call(this)}).call(this,t("_process"))},{_process:32}],8:[function(t,n,e){var r=t("./pointable"),o=t("./bone"),i=t("./dialog"),n=n.exports=function(t){r.call(this,t),this.dipPosition=t.dipPosition,this.pipPosition=t.pipPosition,this.mcpPosition=t.mcpPosition,this.carpPosition=t.carpPosition,this.extended=t.extended,this.type=t.type,this.finger=!0,this.positions=[this.carpPosition,this.mcpPosition,this.pipPosition,this.dipPosition,this.tipPosition],t.bases?this.addBones(t):i.warnBones()};Object.assign(n.prototype,r.prototype),n.prototype.addBones=function(t){this.metacarpal=new o(this,{type:0,width:this.width,prevJoint:this.carpPosition,nextJoint:this.mcpPosition,basis:t.bases[0]}),this.proximal=new o(this,{type:1,width:this.width,prevJoint:this.mcpPosition,nextJoint:this.pipPosition,basis:t.bases[1]}),this.medial=new o(this,{type:2,width:this.width,prevJoint:this.pipPosition,nextJoint:this.dipPosition,basis:t.bases[2]}),this.distal=new o(this,{type:3,width:this.width,prevJoint:this.dipPosition,nextJoint:t.btipPosition,basis:t.bases[3]}),this.bones=[this.metacarpal,this.proximal,this.medial,this.distal]},n.prototype.toString=function(){return"Finger [ id:"+this.id+" "+this.length+"mmx | width:"+this.width+"mm | direction:"+this.direction+" ]"},n.Invalid={valid:!1}},{"./bone":1,"./dialog":7,"./pointable":14}],9:[function(t,n,e){var u=t("./hand"),c=t("./pointable"),r=t("gl-matrix"),o=r.mat3,i=r.vec3,a=t("./interaction_box"),h=t("./finger"),n=n.exports=function(t){this.valid=!0,this.id=t.id,this.timestamp=t.timestamp,this.hands=[],this.handsMap={},this.pointables=[],this.fingers=[],t.interactionBox&&(this.interactionBox=new a(t.interactionBox)),this.pointablesMap={},this._translation=t.t,this._rotation=function e(t){return Array.isArray(t)?t.reduce(function(t,n){return t.concat(e(n))},[]):[t]}(t.r),this._scaleFactor=t.s,this.data=t,this.type="frame",this.currentFrameRate=t.currentFrameRate,this.postprocessData(t)};n.prototype.postprocessData=function(t){for(var n=0,e=(t=t||this.data).hands.length;n!=e;n++){var r=new u(t.hands[n]);(r.frame=this).hands.push(r),this.handsMap[r.id]=r}var o;t.pointables.sort((o="id",function(t,n){return t[o]>n[o]?1:n[o]>t[o]?-1:0}));for(var i=0,a=t.pointables.length;i!=a;i++){var s=t.pointables[i],s=new(s.dipPosition?h:c)(s);(s.frame=this).addPointable(s)}},n.prototype.addPointable=function(t){if(this.pointables.push(t),this.pointablesMap[t.id]=t,this.fingers.push(t),void 0!==t.handId&&this.handsMap.hasOwnProperty(t.handId)){var n=this.handsMap[t.handId];switch(n.pointables.push(t),n.fingers.push(t),t.type){case 0:n.thumb=t;break;case 1:n.indexFinger=t;break;case 2:n.middleFinger=t;break;case 3:n.ringFinger=t;break;case 4:n.pinky=t}}},n.prototype.pointable=function(t){return this.pointablesMap[t]||c.Invalid},n.prototype.finger=function(t){return this.pointable(t)},n.prototype.hand=function(t){return this.handsMap[t]||u.Invalid},n.prototype.rotationAngle=function(t,n){if(!this.valid||!t.valid)return 0;var e=this.rotationMatrix(t),e=.5*(e[0]+e[4]+e[8]-1),e=Math.acos(e),e=isNaN(e)?0:e;return void 0!==n&&(t=this.rotationAxis(t),e*=i.dot(t,i.normalize(i.create(),n))),e},n.prototype.rotationAxis=function(t){return this.valid&&t.valid?i.normalize(i.create(),[this._rotation[7]-t._rotation[5],this._rotation[2]-t._rotation[6],this._rotation[3]-t._rotation[1]]):i.create()},n.prototype.rotationMatrix=function(t){if(!this.valid||!t.valid)return o.create();var n=o.transpose(o.create(),this._rotation);return o.multiply(o.create(),t._rotation,n)},n.prototype.scaleFactor=function(t){return this.valid&&t.valid?Math.exp(this._scaleFactor-t._scaleFactor):1},n.prototype.translation=function(t){return this.valid&&t.valid?i.subtract(i.create(),this._translation,t._translation):i.create()},n.prototype.toString=function(){var t="Frame [ id:"+this.id+" | timestamp:"+this.timestamp+" | Hand count:("+this.hands.length+") | Pointable count:("+this.pointables.length+")";return t+=" ]"},n.prototype.dump=function(){var t="";t+="Frame Info:
",t+=this.toString(),t+="

Hands:
";for(var n=0,e=this.hands.length;n!=e;n++)t+=" "+this.hands[n].toString()+"
";t+="

Pointables:
";for(var r=0,o=this.pointables.length;r!=o;r++)t+=" "+this.pointables[r].toString()+"
";return t+="

Raw JSON:
",t+=JSON.stringify(this.data)},n.Invalid={valid:!1,hands:[],fingers:[],pointables:[],pointable:function(){return c.Invalid},finger:function(){return c.Invalid},hand:function(){return u.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return o.create()},rotationAxis:function(){return i.create()},scaleFactor:function(){return 1},translation:function(){return i.create()}}},{"./finger":8,"./hand":10,"./interaction_box":12,"./pointable":14,"gl-matrix":22}],10:[function(t,n,e){var r=t("./pointable"),o=t("./bone"),t=t("gl-matrix"),i=t.mat3,a=t.vec3,n=n.exports=function(t){this.id=t.id,this.palmPosition=t.palmPosition,this.direction=t.direction,this.palmVelocity=t.palmVelocity,this.palmNormal=t.palmNormal,this.sphereCenter=t.sphereCenter,this.sphereRadius=t.sphereRadius,this.valid=!0,this.pointables=[],this.fingers=[],t.armBasis?this.arm=new o(this,{type:4,width:t.armWidth,prevJoint:t.elbow,nextJoint:t.wrist,basis:t.armBasis}):this.arm=null,this._translation=t.t,this._rotation=function e(t){return Array.isArray(t)?t.reduce(function(t,n){return t.concat(e(n))},[]):[t]}(t.r),this._scaleFactor=t.s,this.timeVisible=t.timeVisible,this.stabilizedPalmPosition=t.stabilizedPalmPosition,this.type=t.type,this.grabStrength=t.grabStrength,this.pinchStrength=t.pinchStrength,this.confidence=t.confidence};n.prototype.finger=function(t){t=this.frame.finger(t);return t&&t.handId==this.id?t:r.Invalid},n.prototype.rotationAngle=function(t,n){if(!this.valid||!t.valid)return 0;if(!t.hand(this.id).valid)return 0;var e=this.rotationMatrix(t),e=.5*(e[0]+e[4]+e[8]-1),e=Math.acos(e),e=isNaN(e)?0:e;return void 0!==n&&(t=this.rotationAxis(t),e*=a.dot(t,a.normalize(a.create(),n))),e},n.prototype.rotationAxis=function(t){if(!this.valid||!t.valid)return a.create();t=t.hand(this.id);return t.valid?a.normalize(a.create(),[this._rotation[7]-t._rotation[5],this._rotation[2]-t._rotation[6],this._rotation[3]-t._rotation[1]]):a.create()},n.prototype.rotationMatrix=function(t){if(!this.valid||!t.valid)return i.create();var n=t.hand(this.id);if(!n.valid)return i.create();t=i.transpose(i.create(),this._rotation);return i.multiply(i.create(),n._rotation,t)},n.prototype.scaleFactor=function(t){if(!this.valid||!t.valid)return 1;t=t.hand(this.id);return t.valid?Math.exp(this._scaleFactor-t._scaleFactor):1},n.prototype.translation=function(t){if(!this.valid||!t.valid)return a.create();t=t.hand(this.id);return t.valid?[this._translation[0]-t._translation[0],this._translation[1]-t._translation[1],this._translation[2]-t._translation[2]]:a.create()},n.prototype.toString=function(){return"Hand ("+this.type+") [ id: "+this.id+" | palm velocity:"+this.palmVelocity+" | sphere center:"+this.sphereCenter+" ] "},n.prototype.pitch=function(){return Math.atan2(this.direction[1],-this.direction[2])},n.prototype.yaw=function(){return Math.atan2(this.direction[0],-this.direction[2])},n.prototype.roll=function(){return Math.atan2(this.palmNormal[0],-this.palmNormal[1])},n.Invalid={valid:!1,fingers:[],pointables:[],left:!1,pointable:function(){return r.Invalid},finger:function(){return r.Invalid},toString:function(){return"invalid frame"},dump:function(){return this.toString()},rotationAngle:function(){return 0},rotationMatrix:function(){return i.create()},rotationAxis:function(){return a.create()},scaleFactor:function(){return 1},translation:function(){return a.create()}}},{"./bone":1,"./pointable":14,"gl-matrix":22}],11:[function(t,n,e){n.exports={Controller:t("./controller"),Frame:t("./frame"),Hand:t("./hand"),Pointable:t("./pointable"),Finger:t("./finger"),InteractionBox:t("./interaction_box"),CircularBuffer:t("./circular_buffer"),UI:t("./ui"),JSONProtocol:t("./protocol").JSONProtocol,glMatrix:t("gl-matrix"),mat3:t("gl-matrix").mat3,vec3:t("gl-matrix").vec3,loopController:void 0,version:t("./version.js"),EventEmitter:t("events").EventEmitter,loop:function(t,n){return t&&void 0===n&&"[object Function]"==={}.toString.call(t)&&(n=t,t={}),this.loopController?t&&this.loopController.setupFrameEvents(t):this.loopController=new this.Controller(t),this.loopController.loop(n),this.loopController},plugin:function(t,n){this.Controller.plugin(t,n)}}},{"./circular_buffer":2,"./controller":6,"./finger":8,"./frame":9,"./hand":10,"./interaction_box":12,"./pointable":14,"./protocol":15,"./ui":16,"./version.js":19,events:20,"gl-matrix":22}],12:[function(t,n,e){var r=t("gl-matrix").vec3,n=n.exports=function(t){this.valid=!0,this.center=t.center,this.size=t.size,this.width=t.size[0],this.height=t.size[1],this.depth=t.size[2]};n.prototype.denormalizePoint=function(t){return r.fromValues((t[0]-.5)*this.size[0]+this.center[0],(t[1]-.5)*this.size[1]+this.center[1],(t[2]-.5)*this.size[2]+this.center[2])},n.prototype.normalizePoint=function(t,n){t=r.fromValues((t[0]-this.center[0])/this.size[0]+.5,(t[1]-this.center[1])/this.size[1]+.5,(t[2]-this.center[2])/this.size[2]+.5);return n&&(t[0]=Math.min(Math.max(t[0],0),1),t[1]=Math.min(Math.max(t[1],0),1),t[2]=Math.min(Math.max(t[2],0),1)),t},n.prototype.toString=function(){return"InteractionBox [ width:"+this.width+" | height:"+this.height+" | depth:"+this.depth+" ]"},n.Invalid={valid:!1}},{"gl-matrix":22}],13:[function(t,n,e){n=n.exports=function(t){this.steps=[],this.controller=t};n.prototype.addStep=function(t){this.steps.push(t)},n.prototype.run=function(t){for(var n=this.steps.length,e=0;e!=n&&t;e++)t=this.steps[e](t);return t},n.prototype.removeStep=function(t){t=this.steps.indexOf(t);if(-1===t)throw"Step not found in pipeline";this.steps.splice(t,1)},n.prototype.addWrappedStep=function(o,i){function t(t){for(var n="frame"==o?[t]:t[o+"s"]||[],e=0,r=n.length;e=this.start.x&&e.x<=this.end.x&&e.y>=this.start.y&&e.y<=this.end.y&&e.z>=this.start.z&&e.z<=this.end.z)return!0}return!1},r.prototype.listener=function(t){var n=this;return t&&t.nearThreshold&&this.setupNearRegion(t.nearThreshold),function(t){return n.updatePosition(t)}},r.prototype.clipper=function(){var n=this;return function(t){return n.updatePosition(t),n.enteredFrame?t:null}},r.prototype.setupNearRegion=function(t){var t=this.nearRegion=new r([this.start.x-t,this.start.y-t,this.start.z-t],[this.end.x+t,this.end.y+t,this.end.z+t]),n=this;t.on("enter",function(t){n.emit("near",t)}),t.on("exit",function(t){n.emit("far",t)}),n.on("exit",function(t){n.emit("near",t)})},r.prototype.updatePosition=function(t){return this.nearRegion&&this.nearRegion.updatePosition(t),this.hasPointables(t)&&null==this.enteredFrame?(this.enteredFrame=t,this.emit("enter",this.enteredFrame)):this.hasPointables(t)||null==this.enteredFrame||(this.enteredFrame=null,this.emit("exit",this.enteredFrame)),t},r.prototype.normalize=function(t){return new Vector([(t.x-this.start.x)/(this.end.x-this.start.x),(t.y-this.start.y)/(this.end.y-this.start.y),(t.z-this.start.z)/(this.end.z-this.start.z)])},r.prototype.mapToXY=function(t,n,e){var r=this.normalize(t),o=r.x,t=r.y;return 1r&&(i.warned=!0,(r=new Error("Possible EventEmitter memory leak detected. "+i.length+' "'+String(n)+'" listeners added. Use emitter.setMaxListeners() to increase limit.')).name="MaxListenersExceededWarning",r.emitter=t,r.type=n,r.count=i.length,"object"==typeof console&&console.warn&&console.warn("%s: %s",r.name,r.message))):(i=o[n]=e,++t._eventsCount),t}function f(){if(!this.fired)switch(this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length){case 0:return this.listener.call(this.target);case 1:return this.listener.call(this.target,arguments[0]);case 2:return this.listener.call(this.target,arguments[0],arguments[1]);case 3:return this.listener.call(this.target,arguments[0],arguments[1],arguments[2]);default:for(var t=new Array(arguments.length),n=0;np.EPSILON?(t[0]=n[0]/r,t[1]=n[1]/r,t[2]=n[2]/r):(t[0]=1,t[1]=0,t[2]=0);return e},e.getAngle=function(t,n){n=b(t,n);return Math.acos(2*n*n-1)},e.multiply=l,e.rotateX=function(t,n,e){e*=.5;var r=n[0],o=n[1],i=n[2],a=n[3],n=Math.sin(e),e=Math.cos(e);return t[0]=r*e+a*n,t[1]=o*e+i*n,t[2]=i*e-o*n,t[3]=a*e-r*n,t},e.rotateY=function(t,n,e){e*=.5;var r=n[0],o=n[1],i=n[2],a=n[3],n=Math.sin(e),e=Math.cos(e);return t[0]=r*e-i*n,t[1]=o*e+a*n,t[2]=i*e+r*n,t[3]=a*e-o*n,t},e.rotateZ=function(t,n,e){e*=.5;var r=n[0],o=n[1],i=n[2],a=n[3],n=Math.sin(e),e=Math.cos(e);return t[0]=r*e+o*n,t[1]=o*e-r*n,t[2]=i*e+a*n,t[3]=a*e-i*n,t},e.calculateW=function(t,n){var e=n[0],r=n[1],n=n[2];return t[0]=e,t[1]=r,t[2]=n,t[3]=Math.sqrt(Math.abs(1-e*e-r*r-n*n)),t},e.exp=f,e.ln=d,e.pow=function(t,n,e){return d(t,n),y(t,t,e),f(t,t),t},e.slerp=m,e.random=function(t){var n=p.RANDOM(),e=p.RANDOM(),r=p.RANDOM(),o=Math.sqrt(1-n),n=Math.sqrt(n);return t[0]=o*Math.sin(2*Math.PI*e),t[1]=o*Math.cos(2*Math.PI*e),t[2]=n*Math.sin(2*Math.PI*r),t[3]=n*Math.cos(2*Math.PI*r),t},e.invert=function(t,n){var e=n[0],r=n[1],o=n[2],i=n[3],n=e*e+r*r+o*o+i*i,n=n?1/n:0;return t[0]=-e*n,t[1]=-r*n,t[2]=-o*n,t[3]=i*n,t},e.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},e.fromMat3=v,e.fromEuler=function(t,n,e,r){var o=.5*Math.PI/180;n*=o,e*=o,r*=o;var i=Math.sin(n),a=Math.cos(n),o=Math.sin(e),n=Math.cos(e),e=Math.sin(r),r=Math.cos(r);return t[0]=i*n*r-a*o*e,t[1]=a*o*r+i*n*e,t[2]=a*n*e-i*o*r,t[3]=a*n*r+i*o*e,t},e.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.setAxes=e.sqlerp=e.rotationTo=e.equals=e.exactEquals=e.normalize=e.sqrLen=e.squaredLength=e.len=e.length=e.lerp=e.dot=e.scale=e.mul=e.add=e.set=e.copy=e.fromValues=e.clone=void 0;var p=u(t("./common.js")),r=u(t("./mat3.js")),o=u(t("./vec3.js")),i=u(t("./vec4.js"));function s(){if("function"!=typeof WeakMap)return null;var t=new WeakMap;return s=function(){return t},t}function u(t){if(t&&t.__esModule)return t;if(null===t||"object"!==a(t)&&"function"!=typeof t)return{default:t};var n=s();if(n&&n.has(t))return n.get(t);var e,r,o={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(e in t)Object.prototype.hasOwnProperty.call(t,e)&&((r=i?Object.getOwnPropertyDescriptor(t,e):null)&&(r.get||r.set)?Object.defineProperty(o,e,r):o[e]=t[e]);return o.default=t,n&&n.set(t,o),o}function c(){var t=new p.ARRAY_TYPE(4);return p.ARRAY_TYPE!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t[3]=1,t}function h(t,n,e){e*=.5;var r=Math.sin(e);return t[0]=r*n[0],t[1]=r*n[1],t[2]=r*n[2],t[3]=Math.cos(e),t}function l(t,n,e){var r=n[0],o=n[1],i=n[2],a=n[3],s=e[0],u=e[1],n=e[2],e=e[3];return t[0]=r*e+a*s+o*n-i*u,t[1]=o*e+a*u+i*s-r*n,t[2]=i*e+a*n+r*u-o*s,t[3]=a*e-r*s-o*u-i*n,t}function f(t,n){var e=n[0],r=n[1],o=n[2],i=n[3],a=Math.sqrt(e*e+r*r+o*o),n=Math.exp(i),i=0p.EPSILON?(e=Math.acos(n),n=Math.sin(e),o=Math.sin((1-r)*e)/n,Math.sin(r*e)/n):(o=1-r,r),t[0]=o*i+r*c,t[1]=o*a+r*h,t[2]=o*s+r*l,t[3]=o*u+r*f,t}function v(t,n){var e,r,o,i=n[0]+n[4]+n[8];return 0n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2),r=(e+1)%3,i=(e+2)%3,o=Math.sqrt(n[3*e+e]-n[3*r+r]-n[3*i+i]+1),t[e]=.5*o,o=.5/o,t[3]=(n[3*r+i]-n[3*i+r])*o,t[r]=(n[3*r+e]+n[3*e+r])*o,t[i]=(n[3*i+e]+n[3*e+i])*o),t}t=i.clone;e.clone=t;t=i.fromValues;e.fromValues=t;t=i.copy;e.copy=t;t=i.set;e.set=t;t=i.add;e.add=t,e.mul=l;var y=i.scale;e.scale=y;var b=i.dot;e.dot=b;t=i.lerp;e.lerp=t;t=i.length;e.length=t,e.len=t;t=i.squaredLength;e.squaredLength=t,e.sqrLen=t;var M=i.normalize;e.normalize=M;t=i.exactEquals;e.exactEquals=t;i=i.equals;e.equals=i;var g,w,P,i=(g=o.create(),w=o.fromValues(1,0,0),P=o.fromValues(0,1,0),function(t,n,e){var r=o.dot(n,e);return r<-.999999?(o.cross(g,w,n),o.len(g)<1e-6&&o.cross(g,P,n),o.normalize(g,g),h(t,g,Math.PI),t):.999999 b[key]) ? 1 : ((b[key] > a[key]) ? -1 : 0) }; + }; + + data.pointables.sort(sortBy("id")); for (var pointableIdx = 0, pointableCount = data.pointables.length; pointableIdx != pointableCount; pointableIdx++) { var pointableData = data.pointables[pointableIdx]; @@ -165,18 +147,18 @@ Frame.prototype.postprocessData = function(data){ /** * Adds data from a pointable element into the pointablesMap; * also adds the pointable to the frame.handsMap hand to which it belongs, - * and to the hand's tools or hand's fingers map. + * and to the hand's fingers map. * * @param pointable {Object} a Pointable */ Frame.prototype.addPointable = function (pointable) { this.pointables.push(pointable); this.pointablesMap[pointable.id] = pointable; - (pointable.tool ? this.tools : this.fingers).push(pointable); + (this.fingers).push(pointable); if (pointable.handId !== undefined && this.handsMap.hasOwnProperty(pointable.handId)) { var hand = this.handsMap[pointable.handId]; hand.pointables.push(pointable); - (pointable.tool ? hand.tools : hand.fingers).push(pointable); + (hand.fingers).push(pointable); switch (pointable.type){ case 0: hand.thumb = pointable; @@ -197,43 +179,18 @@ Frame.prototype.addPointable = function (pointable) { } }; -/** - * The tool with the specified ID in this frame. - * - * Use the Frame tool() function to retrieve a tool from - * this frame using an ID value obtained from a previous frame. - * This function always returns a Pointable object, but if no tool - * with the specified ID is present, an invalid Pointable object is returned. - * - * Note that ID values persist across frames, but only until tracking of a - * particular object is lost. If tracking of a tool is lost and subsequently - * regained, the new Pointable object representing that tool may have a - * different ID than that representing the tool in an earlier frame. - * - * @method tool - * @memberof Leap.Frame.prototype - * @param {String} id The ID value of a Tool object from a previous frame. - * @returns {Leap.Pointable} The tool with the - * matching ID if one exists in this frame; otherwise, an invalid Pointable object - * is returned. - */ -Frame.prototype.tool = function(id) { - var pointable = this.pointable(id); - return pointable.tool ? pointable : Pointable.Invalid; -}; - /** * The Pointable object with the specified ID in this frame. * * Use the Frame pointable() function to retrieve the Pointable object from * this frame using an ID value obtained from a previous frame. - * This function always returns a Pointable object, but if no finger or tool + * This function always returns a Pointable object, but if no finger * with the specified ID is present, an invalid Pointable object is returned. * * Note that ID values persist across frames, but only until tracking of a - * particular object is lost. If tracking of a finger or tool is lost and subsequently - * regained, the new Pointable object representing that finger or tool may have - * a different ID than that representing the finger or tool in an earlier frame. + * particular object is lost. If tracking of a finger is lost and subsequently + * regained, the new Pointable object representing that finger may have + * a different ID than that representing the finger in an earlier frame. * * @method pointable * @memberof Leap.Frame.prototype @@ -267,8 +224,7 @@ Frame.prototype.pointable = function(id) { * object is returned. */ Frame.prototype.finger = function(id) { - var pointable = this.pointable(id); - return !pointable.tool ? pointable : Pointable.Invalid; + return this.pointable(id); }; /** @@ -435,13 +391,12 @@ Frame.prototype.translation = function(sinceFrame) { */ Frame.prototype.toString = function() { var str = "Frame [ id:"+this.id+" | timestamp:"+this.timestamp+" | Hand count:("+this.hands.length+") | Pointable count:("+this.pointables.length+")"; - if (this.gestures) str += " | Gesture count:("+this.gestures.length+")"; str += " ]"; return str; } /** - * Returns a JSON-formatted string containing the hands, pointables and gestures + * Returns a JSON-formatted string containing the hands, pointables * in this frame. * * @method dump @@ -460,12 +415,6 @@ Frame.prototype.dump = function() { for (var pointableIdx = 0, pointableCount = this.pointables.length; pointableIdx != pointableCount; pointableIdx++) { out += " "+ this.pointables[pointableIdx].toString() + "
"; } - if (this.gestures) { - out += "

Gestures:
"; - for (var gestureIdx = 0, gestureCount = this.gestures.length; gestureIdx != gestureCount; gestureIdx++) { - out += " "+ this.gestures[gestureIdx].toString() + "
"; - } - } out += "

Raw JSON:
"; out += JSON.stringify(this.data); return out; @@ -487,8 +436,6 @@ Frame.Invalid = { valid: false, hands: [], fingers: [], - tools: [], - gestures: [], pointables: [], pointable: function() { return Pointable.Invalid }, finger: function() { return Pointable.Invalid }, diff --git a/lib/gesture.js b/lib/gesture.js deleted file mode 100644 index c9021ff5..00000000 --- a/lib/gesture.js +++ /dev/null @@ -1,483 +0,0 @@ -var glMatrix = require("gl-matrix") - , vec3 = glMatrix.vec3 - , EventEmitter = require('events').EventEmitter - , _ = require('underscore'); - -/** - * Constructs a new Gesture object. - * - * An uninitialized Gesture object is considered invalid. Get valid instances - * of the Gesture class, which will be one of the Gesture subclasses, from a - * Frame object. - * - * @class Gesture - * @abstract - * @memberof Leap - * @classdesc - * The Gesture class represents a recognized movement by the user. - * - * The Leap watches the activity within its field of view for certain movement - * patterns typical of a user gesture or command. For example, a movement from side to - * side with the hand can indicate a swipe gesture, while a finger poking forward - * can indicate a screen tap gesture. - * - * When the Leap recognizes a gesture, it assigns an ID and adds a - * Gesture object to the frame gesture list. For continuous gestures, which - * occur over many frames, the Leap updates the gesture by adding - * a Gesture object having the same ID and updated properties in each - * subsequent frame. - * - * **Important:** Recognition for each type of gesture must be enabled; - * otherwise **no gestures are recognized or reported**. - * - * Subclasses of Gesture define the properties for the specific movement patterns - * recognized by the Leap. - * - * The Gesture subclasses for include: - * - * * CircleGesture -- A circular movement by a finger. - * * SwipeGesture -- A straight line movement by the hand with fingers extended. - * * ScreenTapGesture -- A forward tapping movement by a finger. - * * KeyTapGesture -- A downward tapping movement by a finger. - * - * Circle and swipe gestures are continuous and these objects can have a - * state of start, update, and stop. - * - * The screen tap gesture is a discrete gesture. The Leap only creates a single - * ScreenTapGesture object appears for each tap and it always has a stop state. - * - * Get valid Gesture instances from a Frame object. You can get a list of gestures - * from the Frame gestures array. You can also use the Frame gesture() method - * to find a gesture in the current frame using an ID value obtained in a - * previous frame. - * - * Gesture objects can be invalid. For example, when you get a gesture by ID - * using Frame.gesture(), and there is no gesture with that ID in the current - * frame, then gesture() returns an Invalid Gesture object (rather than a null - * value). Always check object validity in situations where a gesture might be - * invalid. - */ -var createGesture = exports.createGesture = function(data) { - var gesture; - switch (data.type) { - case 'circle': - gesture = new CircleGesture(data); - break; - case 'swipe': - gesture = new SwipeGesture(data); - break; - case 'screenTap': - gesture = new ScreenTapGesture(data); - break; - case 'keyTap': - gesture = new KeyTapGesture(data); - break; - default: - throw "unknown gesture type"; - } - - /** - * The gesture ID. - * - * All Gesture objects belonging to the same recognized movement share the - * same ID value. Use the ID value with the Frame::gesture() method to - * find updates related to this Gesture object in subsequent frames. - * - * @member id - * @memberof Leap.Gesture.prototype - * @type {number} - */ - gesture.id = data.id; - /** - * The list of hands associated with this Gesture, if any. - * - * If no hands are related to this gesture, the list is empty. - * - * @member handIds - * @memberof Leap.Gesture.prototype - * @type {Array} - */ - gesture.handIds = data.handIds.slice(); - /** - * The list of fingers and tools associated with this Gesture, if any. - * - * If no Pointable objects are related to this gesture, the list is empty. - * - * @member pointableIds - * @memberof Leap.Gesture.prototype - * @type {Array} - */ - gesture.pointableIds = data.pointableIds.slice(); - /** - * The elapsed duration of the recognized movement up to the - * frame containing this Gesture object, in microseconds. - * - * The duration reported for the first Gesture in the sequence (with the - * start state) will typically be a small positive number since - * the movement must progress far enough for the Leap to recognize it as - * an intentional gesture. - * - * @member duration - * @memberof Leap.Gesture.prototype - * @type {number} - */ - gesture.duration = data.duration; - /** - * The gesture ID. - * - * Recognized movements occur over time and have a beginning, a middle, - * and an end. The 'state()' attribute reports where in that sequence this - * Gesture object falls. - * - * Possible values for the state field are: - * - * * start - * * update - * * stop - * - * @member state - * @memberof Leap.Gesture.prototype - * @type {String} - */ - gesture.state = data.state; - /** - * The gesture type. - * - * Possible values for the type field are: - * - * * circle - * * swipe - * * screenTap - * * keyTap - * - * @member type - * @memberof Leap.Gesture.prototype - * @type {String} - */ - gesture.type = data.type; - return gesture; -} - -/* - * Returns a builder object, which uses method chaining for gesture callback binding. - */ -var gestureListener = exports.gestureListener = function(controller, type) { - var handlers = {}; - var gestureMap = {}; - - controller.on('gesture', function(gesture, frame) { - if (gesture.type == type) { - if (gesture.state == "start" || gesture.state == "stop") { - if (gestureMap[gesture.id] === undefined) { - var gestureTracker = new Gesture(gesture, frame); - gestureMap[gesture.id] = gestureTracker; - _.each(handlers, function(cb, name) { - gestureTracker.on(name, cb); - }); - } - } - gestureMap[gesture.id].update(gesture, frame); - if (gesture.state == "stop") { - delete gestureMap[gesture.id]; - } - } - }); - var builder = { - start: function(cb) { - handlers['start'] = cb; - return builder; - }, - stop: function(cb) { - handlers['stop'] = cb; - return builder; - }, - complete: function(cb) { - handlers['stop'] = cb; - return builder; - }, - update: function(cb) { - handlers['update'] = cb; - return builder; - } - } - return builder; -} - -var Gesture = exports.Gesture = function(gesture, frame) { - this.gestures = [gesture]; - this.frames = [frame]; -} - -Gesture.prototype.update = function(gesture, frame) { - this.lastGesture = gesture; - this.lastFrame = frame; - this.gestures.push(gesture); - this.frames.push(frame); - this.emit(gesture.state, this); -} - -Gesture.prototype.translation = function() { - return vec3.subtract(vec3.create(), this.lastGesture.startPosition, this.lastGesture.position); -} - -_.extend(Gesture.prototype, EventEmitter.prototype); - -/** - * Constructs a new CircleGesture object. - * - * An uninitialized CircleGesture object is considered invalid. Get valid instances - * of the CircleGesture class from a Frame object. - * - * @class CircleGesture - * @memberof Leap - * @augments Leap.Gesture - * @classdesc - * The CircleGesture classes represents a circular finger movement. - * - * A circle movement is recognized when the tip of a finger draws a circle - * within the Leap field of view. - * - * ![CircleGesture](images/Leap_Gesture_Circle.png) - * - * Circle gestures are continuous. The CircleGesture objects for the gesture have - * three possible states: - * - * * start -- The circle gesture has just started. The movement has - * progressed far enough for the recognizer to classify it as a circle. - * * update -- The circle gesture is continuing. - * * stop -- The circle gesture is finished. - */ -var CircleGesture = function(data) { - /** - * The center point of the circle within the Leap frame of reference. - * - * @member center - * @memberof Leap.CircleGesture.prototype - * @type {number[]} - */ - this.center = data.center; - /** - * The normal vector for the circle being traced. - * - * If you draw the circle clockwise, the normal vector points in the same - * general direction as the pointable object drawing the circle. If you draw - * the circle counterclockwise, the normal points back toward the - * pointable. If the angle between the normal and the pointable object - * drawing the circle is less than 90 degrees, then the circle is clockwise. - * - * ```javascript - * var clockwiseness; - * if (circle.pointable.direction.angleTo(circle.normal) <= PI/4) { - * clockwiseness = "clockwise"; - * } - * else - * { - * clockwiseness = "counterclockwise"; - * } - * ``` - * - * @member normal - * @memberof Leap.CircleGesture.prototype - * @type {number[]} - */ - this.normal = data.normal; - /** - * The number of times the finger tip has traversed the circle. - * - * Progress is reported as a positive number of the number. For example, - * a progress value of .5 indicates that the finger has gone halfway - * around, while a value of 3 indicates that the finger has gone around - * the the circle three times. - * - * Progress starts where the circle gesture began. Since the circle - * must be partially formed before the Leap can recognize it, progress - * will be greater than zero when a circle gesture first appears in the - * frame. - * - * @member progress - * @memberof Leap.CircleGesture.prototype - * @type {number} - */ - this.progress = data.progress; - /** - * The radius of the circle in mm. - * - * @member radius - * @memberof Leap.CircleGesture.prototype - * @type {number} - */ - this.radius = data.radius; -} - -CircleGesture.prototype.toString = function() { - return "CircleGesture ["+JSON.stringify(this)+"]"; -} - -/** - * Constructs a new SwipeGesture object. - * - * An uninitialized SwipeGesture object is considered invalid. Get valid instances - * of the SwipeGesture class from a Frame object. - * - * @class SwipeGesture - * @memberof Leap - * @augments Leap.Gesture - * @classdesc - * The SwipeGesture class represents a swiping motion of a finger or tool. - * - * ![SwipeGesture](images/Leap_Gesture_Swipe.png) - * - * Swipe gestures are continuous. - */ -var SwipeGesture = function(data) { - /** - * The starting position within the Leap frame of - * reference, in mm. - * - * @member startPosition - * @memberof Leap.SwipeGesture.prototype - * @type {number[]} - */ - this.startPosition = data.startPosition; - /** - * The current swipe position within the Leap frame of - * reference, in mm. - * - * @member position - * @memberof Leap.SwipeGesture.prototype - * @type {number[]} - */ - this.position = data.position; - /** - * The unit direction vector parallel to the swipe motion. - * - * You can compare the components of the vector to classify the swipe as - * appropriate for your application. For example, if you are using swipes - * for two dimensional scrolling, you can compare the x and y values to - * determine if the swipe is primarily horizontal or vertical. - * - * @member direction - * @memberof Leap.SwipeGesture.prototype - * @type {number[]} - */ - this.direction = data.direction; - /** - * The speed of the finger performing the swipe gesture in - * millimeters per second. - * - * @member speed - * @memberof Leap.SwipeGesture.prototype - * @type {number} - */ - this.speed = data.speed; -} - -SwipeGesture.prototype.toString = function() { - return "SwipeGesture ["+JSON.stringify(this)+"]"; -} - -/** - * Constructs a new ScreenTapGesture object. - * - * An uninitialized ScreenTapGesture object is considered invalid. Get valid instances - * of the ScreenTapGesture class from a Frame object. - * - * @class ScreenTapGesture - * @memberof Leap - * @augments Leap.Gesture - * @classdesc - * The ScreenTapGesture class represents a tapping gesture by a finger or tool. - * - * A screen tap gesture is recognized when the tip of a finger pokes forward - * and then springs back to approximately the original postion, as if - * tapping a vertical screen. The tapping finger must pause briefly before beginning the tap. - * - * ![ScreenTap](images/Leap_Gesture_Tap2.png) - * - * ScreenTap gestures are discrete. The ScreenTapGesture object representing a tap always - * has the state, STATE_STOP. Only one ScreenTapGesture object is created for each - * screen tap gesture recognized. - */ -var ScreenTapGesture = function(data) { - /** - * The position where the screen tap is registered. - * - * @member position - * @memberof Leap.ScreenTapGesture.prototype - * @type {number[]} - */ - this.position = data.position; - /** - * The direction of finger tip motion. - * - * @member direction - * @memberof Leap.ScreenTapGesture.prototype - * @type {number[]} - */ - this.direction = data.direction; - /** - * The progess value is always 1.0 for a screen tap gesture. - * - * @member progress - * @memberof Leap.ScreenTapGesture.prototype - * @type {number} - */ - this.progress = data.progress; -} - -ScreenTapGesture.prototype.toString = function() { - return "ScreenTapGesture ["+JSON.stringify(this)+"]"; -} - -/** - * Constructs a new KeyTapGesture object. - * - * An uninitialized KeyTapGesture object is considered invalid. Get valid instances - * of the KeyTapGesture class from a Frame object. - * - * @class KeyTapGesture - * @memberof Leap - * @augments Leap.Gesture - * @classdesc - * The KeyTapGesture class represents a tapping gesture by a finger or tool. - * - * A key tap gesture is recognized when the tip of a finger rotates down toward the - * palm and then springs back to approximately the original postion, as if - * tapping. The tapping finger must pause briefly before beginning the tap. - * - * ![KeyTap](images/Leap_Gesture_Tap.png) - * - * Key tap gestures are discrete. The KeyTapGesture object representing a tap always - * has the state, STATE_STOP. Only one KeyTapGesture object is created for each - * key tap gesture recognized. - */ -var KeyTapGesture = function(data) { - /** - * The position where the key tap is registered. - * - * @member position - * @memberof Leap.KeyTapGesture.prototype - * @type {number[]} - */ - this.position = data.position; - /** - * The direction of finger tip motion. - * - * @member direction - * @memberof Leap.KeyTapGesture.prototype - * @type {number[]} - */ - this.direction = data.direction; - /** - * The progess value is always 1.0 for a key tap gesture. - * - * @member progress - * @memberof Leap.KeyTapGesture.prototype - * @type {number} - */ - this.progress = data.progress; -} - -KeyTapGesture.prototype.toString = function() { - return "KeyTapGesture ["+JSON.stringify(this)+"]"; -} diff --git a/lib/hand.js b/lib/hand.js index 5fc78cba..f77a1ba8 100644 --- a/lib/hand.js +++ b/lib/hand.js @@ -2,8 +2,7 @@ var Pointable = require("./pointable") , Bone = require('./bone') , glMatrix = require("gl-matrix") , mat3 = glMatrix.mat3 - , vec3 = glMatrix.vec3 - , _ = require("underscore"); + , vec3 = glMatrix.vec3; /** * Constructs a Hand object. @@ -17,7 +16,7 @@ var Pointable = require("./pointable") * * Hand tracking data includes a palm position and velocity; vectors for * the palm normal and direction to the fingers; properties of a sphere fit - * to the hand; and lists of the attached fingers and tools. + * to the hand; and lists of the attached fingers. * * Note that Hand objects can be invalid, which means that they do not contain * valid tracking data and do not correspond to a physical entity. Invalid Hand @@ -112,14 +111,13 @@ var Hand = module.exports = function(data) { */ this.valid = true; /** - * The list of Pointable objects (fingers and tools) detected in this frame + * The list of Pointable objects (fingers) detected in this frame * that are associated with this hand, given in arbitrary order. The list * can be empty if no fingers or tools associated with this hand are detected. * * Use the {@link Pointable} tool property to determine * whether or not an item in the list represents a tool or finger. - * You can also get only the tools using the Hand.tools[] list or - * only the fingers using the Hand.fingers[] list. + * You can also get only the fingers using the Hand.fingers[] list. * * @member pointables[] * @memberof Leap.Hand.prototype @@ -150,19 +148,13 @@ var Hand = module.exports = function(data) { this.arm = null; } - /** - * The list of tools detected in this frame that are held by this - * hand, given in arbitrary order. - * - * The list can be empty if no tools held by this hand are detected. - * - * @member tools[] - * @memberof Leap.Hand.prototype - * @type {Leap.Pointable[]} - */ - this.tools = []; this._translation = data.t; - this._rotation = _.flatten(data.r); + function flattenDeep(arr) { + return Array.isArray(arr) + ? arr.reduce(function (a, b) { return a.concat(flattenDeep(b)) }, []) + : [arr]; + } + this._rotation = flattenDeep(data.r); this._scaleFactor = data.s; /** @@ -223,7 +215,7 @@ Hand.prototype.finger = function(id) { /** * The angle of rotation around the rotation axis derived from the change in - * orientation of this hand, and any associated fingers and tools, between the + * orientation of this hand, and any associated fingers, between the * current frame and the specified frame. * * The returned angle is expressed in radians measured clockwise around the @@ -258,7 +250,7 @@ Hand.prototype.rotationAngle = function(sinceFrame, axis) { /** * The axis of rotation derived from the change in orientation of this hand, and - * any associated fingers and tools, between the current frame and the specified frame. + * any associated fingers, between the current frame and the specified frame. * * The returned direction vector is normalized. * @@ -284,7 +276,7 @@ Hand.prototype.rotationAxis = function(sinceFrame) { /** * The transform matrix expressing the rotation derived from the change in - * orientation of this hand, and any associated fingers and tools, between + * orientation of this hand, and any associated fingers, between * the current frame and the specified frame. * * If a corresponding Hand object is not found in sinceFrame, or if either @@ -313,7 +305,7 @@ Hand.prototype.rotationMatrix = function(sinceFrame) { * Values between 0.0 and 1.0 indicate contraction and values greater than 1.0 indicate expansion. * * The Leap derives scaling from the relative inward or outward motion of a hand - * and its associated fingers and tools (independent of translation and rotation). + * and its associated fingers (independent of translation and rotation). * * If a corresponding Hand object is not found in sinceFrame, or if either this frame or sinceFrame * are invalid Frame objects, then this method returns 1.0. @@ -437,7 +429,6 @@ Hand.prototype.roll = function() { Hand.Invalid = { valid: false, fingers: [], - tools: [], pointables: [], left: false, pointable: function() { return Pointable.Invalid }, diff --git a/lib/index.js b/lib/index.js index 32ef4274..fd3d6b09 100644 --- a/lib/index.js +++ b/lib/index.js @@ -5,7 +5,6 @@ module.exports = { Controller: require("./controller"), Frame: require("./frame"), - Gesture: require("./gesture"), Hand: require("./hand"), Pointable: require("./pointable"), Finger: require("./finger"), @@ -22,9 +21,7 @@ module.exports = { /** * Expose utility libraries for convenience * Use carefully - they may be subject to upgrade or removal in different versions of LeapJS. - * */ - _: require('underscore'), EventEmitter: require('events').EventEmitter, /** diff --git a/lib/pipeline.js b/lib/pipeline.js index 0ed8e48f..9dee03ec 100644 --- a/lib/pipeline.js +++ b/lib/pipeline.js @@ -31,7 +31,7 @@ Pipeline.prototype.removeStep = function(step){ * @memberOf Leap.Controller.prototype * @param {Controller} The controller on which the callback is called. * @param {String} type What frame object the callback is run for and receives. - * Can be one of 'frame', 'finger', 'hand', 'pointable', 'tool' + * Can be one of 'frame', 'finger', 'hand', 'pointable' * @param {function} callback The method which will be run inside the pipeline loop. Receives one argument, such as a hand. * @private */ diff --git a/lib/protocol.js b/lib/protocol.js index 43464457..66967f9e 100644 --- a/lib/protocol.js +++ b/lib/protocol.js @@ -1,8 +1,4 @@ var Frame = require('./frame') - , Hand = require('./hand') - , Pointable = require('./pointable') - , Finger = require('./finger') - , _ = require('underscore') , EventEmitter = require('events').EventEmitter; var Event = function(data) { @@ -66,7 +62,7 @@ var JSONProtocol = exports.JSONProtocol = function(header) { protocol.versionLong = 'Version ' + header.version; protocol.type = 'protocol'; - _.extend(protocol, EventEmitter.prototype); + Object.assign(protocol, EventEmitter.prototype); return protocol; }; diff --git a/lib/ui/region.js b/lib/ui/region.js index 47167d7f..910971da 100644 --- a/lib/ui/region.js +++ b/lib/ui/region.js @@ -1,5 +1,4 @@ -var EventEmitter = require('events').EventEmitter - , _ = require('underscore') +var EventEmitter = require('events').EventEmitter; var Region = module.exports = function(start, end) { this.start = new Vector(start) @@ -84,4 +83,4 @@ Region.prototype.mapToXY = function(position, width, height) { ] } -_.extend(Region.prototype, EventEmitter.prototype) \ No newline at end of file +Object.assign(Region.prototype, EventEmitter.prototype) \ No newline at end of file diff --git a/lib/version.js b/lib/version.js index 89fcca88..a2552d2c 100644 --- a/lib/version.js +++ b/lib/version.js @@ -1,7 +1,7 @@ // This file is automatically updated from package.json by grunt. module.exports = { - full: '1.0.0', + full: '1.1.0', major: 1, - minor: 0, + minor: 1, dot: 0 } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9772153a..7410ec93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,30 @@ { "name": "leapjs", - "version": "1.0.0", + "version": "1.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/parser": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz", - "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", + "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", "dev": true }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -17,9 +32,26 @@ "dev": true }, "@types/node": { - "version": "12.12.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.17.tgz", - "integrity": "sha512-Is+l3mcHvs47sKy+afn2O1rV4ldZFU7W8101cNlOd+MRbjM4Onida8jSZnJdTe/0Pcf25g9BNIUsuugmE6puHA==", + "version": "14.14.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.8.tgz", + "integrity": "sha512-z/5Yd59dCKI5kbxauAJgw6dLPzW+TNOItNE00PkpzNwUIEwdj/Lsqwq94H5DdYBX7C13aRA0CY32BK76+neEUA==", + "dev": true, + "optional": true + }, + "@types/yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, "JSONStream": { @@ -39,9 +71,9 @@ "dev": true }, "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-node": { @@ -56,24 +88,58 @@ } }, "acorn-walk": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.0.0.tgz", - "integrity": "sha512-7Bv1We7ZGuU79zZbb6rRqcpxo3OY+zrdtloZWoyD8fmGX+FeXRjE+iuGkZjSXLVovLzrsvMGMy0EkwA0E0umxg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", "dev": true }, "ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", "dev": true, "requires": { - "string-width": "^2.0.0" + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } } }, "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "ansi-regex": { @@ -83,10 +149,13 @@ "dev": true }, "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } }, "anymatch": { "version": "2.0.0", @@ -105,6 +174,84 @@ "dev": true, "requires": { "sprintf-js": "~1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + } + } + }, + "args": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/args/-/args-5.0.1.tgz", + "integrity": "sha512-1kqmFCFsPffavQFGt8OxJdIcETti99kySRUPMpOhaGjL6mRJn8HFU1OxKY5bMqfZKUwTQc1mZkAjmGYaVOHFtQ==", + "dev": true, + "requires": { + "camelcase": "5.0.0", + "chalk": "2.4.2", + "leven": "2.1.0", + "mri": "1.1.4" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "arr-diff": { @@ -131,10 +278,16 @@ "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", "dev": true }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true }, "array-union": { @@ -156,14 +309,23 @@ "dev": true }, "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "dev": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "assert": { @@ -206,13 +368,10 @@ "dev": true }, "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true }, "async-each": { "version": "1.0.3", @@ -220,12 +379,6 @@ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", @@ -294,9 +447,15 @@ } }, "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "basic-auth": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", + "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=", "dev": true }, "binary-extensions": { @@ -305,6 +464,50 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bl": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", + "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -312,9 +515,9 @@ "dev": true }, "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", "dev": true }, "body": { @@ -330,59 +533,67 @@ } }, "boxen": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", - "dev": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "ansi-regex": "^5.0.0" } } } @@ -447,20 +658,12 @@ } }, "browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", + "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", "dev": true, "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } + "resolve": "^1.17.0" } }, "browser-stdout": { @@ -470,17 +673,17 @@ "dev": true }, "browserify": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.0.tgz", - "integrity": "sha512-6bfI3cl76YLAnCZ75AGu/XPOsqUhRyc0F/olGIJeCxtfxF2HvPKEcmjU9M8oAPxl4uBY1U7Nry33Q6koV3f2iw==", + "version": "16.5.2", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.2.tgz", + "integrity": "sha512-TkOR1cQGdmXU9zW4YukWzWVSJwrxmNdADFbqbE3HFgQWe5wqZmOawqZ7J/8MPCwk/W8yY7Y0h+7mOtcZxLP23g==", "dev": true, "requires": { "JSONStream": "^1.0.3", "assert": "^1.4.0", "browser-pack": "^6.0.1", - "browser-resolve": "^1.11.0", + "browser-resolve": "^2.0.0", "browserify-zlib": "~0.2.0", - "buffer": "^5.0.2", + "buffer": "~5.2.1", "cached-path-relative": "^1.0.0", "concat-stream": "^1.6.0", "console-browserify": "^1.1.0", @@ -498,8 +701,8 @@ "inherits": "~2.0.1", "insert-module-globals": "^7.0.0", "labeled-stream-splicer": "^2.0.0", - "mkdirp": "^0.5.0", - "module-deps": "^6.0.0", + "mkdirp-classic": "^0.5.2", + "module-deps": "^6.2.3", "os-browserify": "~0.3.0", "parents": "^1.0.1", "path-browserify": "~0.0.0", @@ -523,75 +726,6 @@ "util": "~0.10.1", "vm-browserify": "^1.0.0", "xtend": "^4.0.0" - }, - "dependencies": { - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", - "dev": true - } - } - } } }, "browserify-aes": { @@ -617,14 +751,6 @@ "async": "^1.5.2", "through2": "^2.0.0", "xtend": "^4.0.0" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - } } }, "browserify-cipher": { @@ -681,28 +807,43 @@ } }, "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", "dev": true, "requires": { - "bn.js": "^4.1.0", + "bn.js": "^5.0.0", "randombytes": "^2.0.1" } }, "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } } }, "browserify-zlib": { @@ -715,15 +856,21 @@ } }, "buffer": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz", - "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", "dev": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -765,6 +912,29 @@ "unset-value": "^1.0.0" } }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, "cached-path-relative": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", @@ -772,25 +942,9 @@ "dev": true }, "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, - "capture-stack-trace": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", - "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "catharsis": { @@ -817,24 +971,13 @@ } }, "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - } + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "check-error": { @@ -863,618 +1006,13 @@ "upath": "^1.1.1" }, "dependencies": { - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, - "optional": true, "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.3.0.tgz", - "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", - "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", - "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz", - "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", - "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true, - "optional": true - } + "is-extglob": "^2.1.1" } }, "normalize-path": { @@ -1485,56 +1023,16 @@ } } }, - "chrome-launcher": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.11.2.tgz", - "integrity": "sha512-jx0kJDCXdB2ARcDMwNCtrf04oY1Up4rOmVu+fqJ5MTPOOIG8EhRcEU9NZfXZc6dMw9FU8o1r21PNp8V2M0zQ+g==", - "dev": true, - "requires": { - "@types/node": "*", - "is-wsl": "^2.1.0", - "lighthouse-logger": "^1.0.0", - "mkdirp": "0.5.1", - "rimraf": "^2.6.1" - } - }, - "chrome-remote-interface": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/chrome-remote-interface/-/chrome-remote-interface-0.28.0.tgz", - "integrity": "sha512-md2qSn6rc/fADlN+Blk2UWNg0SGPYjH2s68piaPN9e62HItKm6uWeXXHh0+28Bq10oaWw8fzNAm1itDFJ+nS4w==", - "dev": true, - "requires": { - "commander": "2.11.x", - "ws": "^6.1.0" - }, - "dependencies": { - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - } - } - }, - "chrome-unmirror": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chrome-unmirror/-/chrome-unmirror-0.1.0.tgz", - "integrity": "sha1-6a94ukf3/7kAYCk6cgoBzSbVC6s=", + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true }, "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, "cipher-base": { @@ -1571,9 +1069,9 @@ } }, "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "dev": true }, "cliui": { @@ -1615,6 +1113,15 @@ } } }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -1626,18 +1133,18 @@ } }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "colors": { @@ -1658,12 +1165,6 @@ "source-map": "~0.5.3" } }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -1676,18 +1177,30 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, "configstore": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", "dev": true, "requires": { - "dot-prop": "^4.1.0", + "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" } }, "console-browserify": { @@ -1726,23 +1239,28 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true + }, "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", "dev": true, "requires": { "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "dev": true, - "requires": { - "capture-stack-trace": "^1.0.0" + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "create-hash": { @@ -1772,17 +1290,6 @@ "sha.js": "^2.4.8" } }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -1803,20 +1310,11 @@ } }, "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, "dash-ast": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", @@ -1824,30 +1322,18 @@ "dev": true }, "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" - } + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "ms": "^2.1.1" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "ms": "2.0.0" } }, "decamelize": { @@ -1856,29 +1342,19 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, - "decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", - "dev": true, - "requires": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - } - }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, - "deep-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-3.0.0.tgz", - "integrity": "sha512-YX2i9XjJ7h5q/aQ/IM9PEwEnDqETAIYbggmdDB3HLTlSgo1CxPsj6pvhPG68rq6SVE0+p+6Ywsm5fTYNrYtBWw==", + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "dev": true, "requires": { - "is-obj": "^1.0.0" + "mimic-response": "^1.0.0" } }, "deep-eql": { @@ -1896,14 +1372,11 @@ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, - "define-properties": { + "defer-to-connect": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true }, "define-property": { "version": "2.0.2", @@ -1974,6 +1447,12 @@ "minimalistic-assert": "^1.0.0" } }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, "detective": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", @@ -1983,20 +1462,12 @@ "acorn-node": "^1.6.1", "defined": "^1.0.0", "minimist": "^1.1.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, "diffie-hellman": { @@ -2008,6 +1479,14 @@ "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "domain-browser": { @@ -2017,18 +1496,18 @@ "dev": true }, "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, "requires": { - "is-obj": "^1.0.0" + "is-obj": "^2.0.0" } }, "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, "duplexer2": { @@ -2046,6 +1525,18 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, + "ecstatic": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.2.tgz", + "integrity": "sha512-fLf9l1hnwrHI2xn9mEDT7KIi22UDqA2jaCwyCbSUJh9a1V+LEUSL/JO/6TIz/QyuBURWUHrFL5Kg2TtO1bkkog==", + "dev": true, + "requires": { + "he": "^1.1.1", + "mime": "^1.6.0", + "minimist": "^1.1.0", + "url-join": "^2.0.5" + } + }, "elliptic": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", @@ -2059,6 +1550,14 @@ "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0", "minimalistic-crypto-utils": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "emoji-regex": { @@ -2067,10 +1566,19 @@ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", "dev": true }, "error": { @@ -2082,48 +1590,16 @@ "string-template": "~0.2.1" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.3.tgz", - "integrity": "sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true }, "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "esprima": { @@ -2138,6 +1614,12 @@ "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", "dev": true }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, "events": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", @@ -2154,21 +1636,6 @@ "safe-buffer": "^5.1.1" } }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -2190,15 +1657,6 @@ "to-regex": "^3.0.1" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -2219,6 +1677,21 @@ } } }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", @@ -2305,6 +1778,35 @@ } } }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, "fast-safe-stringify": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", @@ -2320,6 +1822,15 @@ "websocket-driver": ">=0.5.1" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", @@ -2328,16 +1839,15 @@ "requires": { "escape-string-regexp": "^1.0.5", "object-assign": "^4.1.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - } } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -2362,13 +1872,12 @@ } }, "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "locate-path": "^3.0.0" } }, "findup-sync": { @@ -2395,29 +1904,52 @@ } } }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", "dev": true, "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" } }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "follow-redirects": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==", + "dev": true + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -2427,6 +1959,12 @@ "map-cache": "^0.2.2" } }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2434,11 +1972,15 @@ "dev": true }, "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, - "optional": true + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } }, "function-bind": { "version": "1.1.1", @@ -2473,17 +2015,14 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } }, "get-value": { "version": "2.0.6", @@ -2498,9 +2037,9 @@ "dev": true }, "gl-matrix": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.1.0.tgz", - "integrity": "sha512-526NA+3EA+ztAQi0IZpSWiM0fyQXIp7IbRvfJ4wS/TjjQD0uv0fVybXwwqqSOlq33UckivI0yMDlVtboWm3k7A==" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.3.0.tgz", + "integrity": "sha512-COb7LDz+SXaHtl/h4LeaFcNdJdAQSDeVqjiIihSXNrkWObZLhDI4hIkZC11Aeqp7bcE72clzB0BnDXr2SmslRA==" }, "glob": { "version": "7.1.6", @@ -2524,40 +2063,45 @@ "requires": { "is-glob": "^3.1.0", "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } } }, "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", + "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", "dev": true, "requires": { - "ini": "^1.3.4" - }, - "dependencies": { - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - } + "ini": "^1.3.5" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" } }, "globule": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", - "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", "dev": true, "requires": { "glob": "~7.1.1", @@ -2566,28 +2110,39 @@ } }, "got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", "dev": true, "requires": { - "create-error-class": "^3.0.0", + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "dependencies": { + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + } } }, "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "growl": { @@ -2597,89 +2152,49 @@ "dev": true }, "grunt": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.4.tgz", - "integrity": "sha512-PYsMOrOC+MsdGEkFVwMaMyc6Ob7pKmq+deg1Sjr+vvMWp35sztfwKE7qoN51V+UEtHsyNuMcGdgMLFkBHvMxHQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.3.0.tgz", + "integrity": "sha512-6ILlMXv11/4cxuhSMfSU+SfvbxrPuqZrAtLN64+tZpQ3DAKfSQPQHRbTjSbdtxfyQhGZPtN0bDZJ/LdCM5WXXA==", "dev": true, "requires": { - "coffeescript": "~1.10.0", - "dateformat": "~1.0.12", + "dateformat": "~3.0.3", "eventemitter2": "~0.4.13", - "exit": "~0.1.1", + "exit": "~0.1.2", "findup-sync": "~0.3.0", - "glob": "~7.0.0", - "grunt-cli": "~1.2.0", + "glob": "~7.1.6", + "grunt-cli": "~1.3.2", "grunt-known-options": "~1.1.0", - "grunt-legacy-log": "~2.0.0", - "grunt-legacy-util": "~1.1.1", + "grunt-legacy-log": "~3.0.0", + "grunt-legacy-util": "~2.0.0", "iconv-lite": "~0.4.13", - "js-yaml": "~3.13.0", - "minimatch": "~3.0.2", - "mkdirp": "~0.5.1", + "js-yaml": "~3.14.0", + "minimatch": "~3.0.4", + "mkdirp": "~1.0.4", "nopt": "~3.0.6", - "path-is-absolute": "~1.0.0", - "rimraf": "~2.6.2" + "rimraf": "~3.0.2" }, "dependencies": { - "coffeescript": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz", - "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=", - "dev": true - }, - "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "grunt-cli": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", - "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz", + "integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==", "dev": true, "requires": { - "findup-sync": "~0.3.0", "grunt-known-options": "~1.1.0", - "nopt": "~3.0.6", - "resolve": "~1.1.0" - } - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" + "interpret": "~1.1.0", + "liftoff": "~2.5.0", + "nopt": "~4.0.1", + "v8flags": "~3.1.1" }, "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "abbrev": "1", + "osenv": "^0.1.4" } } } @@ -2693,6 +2208,33 @@ "dev": true, "requires": { "chalk": "^1.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } } }, "grunt-browserify": { @@ -2708,6 +2250,17 @@ "lodash": "^4.17.4", "resolve": "^1.1.6", "watchify": "^3.6.1" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + } } }, "grunt-contrib-clean": { @@ -2718,6 +2271,26 @@ "requires": { "async": "^2.6.1", "rimraf": "^2.6.2" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "grunt-contrib-uglify": { @@ -2752,16 +2325,25 @@ "supports-color": "^5.3.0" } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "supports-color": { @@ -2772,16 +2354,6 @@ "requires": { "has-flag": "^3.0.0" } - }, - "uglify-js": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.2.tgz", - "integrity": "sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA==", - "dev": true, - "requires": { - "commander": "~2.20.3", - "source-map": "~0.6.1" - } } } }, @@ -2795,6 +2367,17 @@ "gaze": "^1.1.0", "lodash": "^4.17.10", "tiny-lr": "^1.1.1" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + } } }, "grunt-exec": { @@ -2810,85 +2393,40 @@ "dev": true }, "grunt-legacy-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz", - "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", + "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", "dev": true, "requires": { "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.0.0", + "grunt-legacy-log-utils": "~2.1.0", "hooker": "~0.2.3", - "lodash": "~4.17.5" + "lodash": "~4.17.19" } }, "grunt-legacy-log-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz", - "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", + "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", "dev": true, "requires": { - "chalk": "~2.4.1", - "lodash": "~4.17.10" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "chalk": "~4.1.0", + "lodash": "~4.17.19" } }, "grunt-legacy-util": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz", - "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.0.tgz", + "integrity": "sha512-ZEmYFB44bblwPE2oz3q3ygfF6hseQja9tx8I3UZIwbUik32FMWewA+d1qSFicMFB+8dNXDkh35HcDCWlpRsGlA==", "dev": true, "requires": { "async": "~1.5.2", "exit": "~0.1.1", "getobject": "~0.1.0", "hooker": "~0.2.3", - "lodash": "~4.17.10", - "underscore.string": "~3.3.4", + "lodash": "~4.17.20", + "underscore.string": "~3.3.5", "which": "~1.3.0" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - } } }, "grunt-string-replace": { @@ -2899,6 +2437,42 @@ "requires": { "async": "^2.0.0", "chalk": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } } }, "gzip-size": { @@ -2929,15 +2503,9 @@ } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "has-value": { @@ -2972,14 +2540,34 @@ } } }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } } }, "hash.js": { @@ -3009,265 +2597,73 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, "hooker": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", "dev": true }, - "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", - "dev": true - }, "htmlescape": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", "dev": true }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz", + "integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ==", "dev": true }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, "http-server": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.12.0.tgz", - "integrity": "sha1-MWtFBgPARU1KRi2XoxMoCKmFhWM=", + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.12.3.tgz", + "integrity": "sha512-be0dKG6pni92bRjq0kvExtj/NrrAd28/8fCXkaI/4piTwQMSDSLMhWyW0NI1V+DBI3aa1HMlQu46/HjVLfmugA==", "dev": true, "requires": { "basic-auth": "^1.0.3", - "colors": "^1.3.3", + "colors": "^1.4.0", "corser": "^2.0.1", "ecstatic": "^3.3.2", - "http-proxy": "^1.17.0", + "http-proxy": "^1.18.0", + "minimist": "^1.2.5", "opener": "^1.5.1", - "optimist": "~0.6.1", - "portfinder": "^1.0.20", + "portfinder": "^1.0.25", "secure-compare": "3.0.1", "union": "~0.5.0" }, "dependencies": { - "basic-auth": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", - "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=", - "dev": true - }, "colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha1-xQSRR51MG9rtLJztMs98fcI2D3g=", - "dev": true - }, - "corser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", - "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", - "dev": true - }, - "ecstatic": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.2.tgz", - "integrity": "sha1-bR3UmBTQBZRoLGUq22YHamnUbEg=", - "dev": true, - "requires": { - "he": "^1.1.1", - "mime": "^1.6.0", - "minimist": "^1.1.0", - "url-join": "^2.0.5" - }, - "dependencies": { - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=", - "dev": true - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "url-join": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", - "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", - "dev": true - } - } - }, - "http-proxy": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", - "integrity": "sha1-2+VfY+daNH2389mZdPJpKjFKajo=", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "dependencies": { - "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha1-1lF2FjiH7lnzhtZMgmELaWpKdOs=", - "dev": true - }, - "follow-redirects": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", - "integrity": "sha1-jVvNxltxCP4VCGScecEtcy3O208=", - "dev": true, - "requires": { - "debug": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha1-6D0X3hbYp++3cX7b5fsQE17uYps=", - "dev": true, - "requires": { - "ms": "^2.1.1" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", - "dev": true - } - } - } - } - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - } - } - }, - "opener": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", - "integrity": "sha1-bS8Od/GgrwAyrKcWwsH7uOfoq+0=", - "dev": true - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - } - } - }, - "portfinder": { - "version": "1.0.25", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", - "integrity": "sha1-JU/TN/+6hp9LnTftwpgFnLTTXso=", - "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.1" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha1-1yYl4jRKNlbjo61Pp0n6gymdgv8=", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha1-6D0X3hbYp++3cX7b5fsQE17uYps=", - "dev": true, - "requires": { - "ms": "^2.1.1" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", - "dev": true - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - } - } - }, - "secure-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", - "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true - }, - "union": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", - "integrity": "sha1-ssEb6E9gU4U3uEbtuboma6AJAHU=", - "dev": true, - "requires": { - "qs": "^6.4.0" - }, - "dependencies": { - "qs": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz", - "integrity": "sha1-IAgsZct4IjY1qxqerKiHWim/jsk=", - "dev": true - } - } } } }, @@ -3277,6 +2673,33 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "dev": true, + "requires": { + "agent-base": "5", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -3287,9 +2710,9 @@ } }, "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true }, "ignore-by-default": { @@ -3304,31 +2727,12 @@ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dev": true, - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - } - }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -3345,6 +2749,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, "inline-source-map": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", @@ -3355,9 +2765,9 @@ } }, "insert-module-globals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", - "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz", + "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==", "dev": true, "requires": { "JSONStream": "^1.0.3", @@ -3370,56 +2780,22 @@ "through2": "^2.0.0", "undeclared-identifiers": "^1.1.2", "xtend": "^4.0.0" - }, - "dependencies": { - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" } }, "is-accessor-descriptor": { @@ -3442,12 +2818,6 @@ } } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -3463,19 +2833,22 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, "is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", + "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", "dev": true, "requires": { - "ci-info": "^1.5.0" + "has": "^1.0.3" } }, "is-data-descriptor": { @@ -3498,12 +2871,6 @@ } } }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -3535,15 +2902,6 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -3551,28 +2909,28 @@ "dev": true }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "^2.1.1" + "is-extglob": "^2.1.0" } }, "is-installed-globally": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", - "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", "dev": true, "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" } }, "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", "dev": true }, "is-number": { @@ -3596,24 +2954,21 @@ } }, "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true }, "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-plain-object": { @@ -3625,58 +2980,40 @@ "isobject": "^3.0.1" } }, - "is-redirect": { + "is-relative": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "requires": { - "has": "^1.0.1" + "is-unc-path": "^1.0.0" } }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "unc-path-regex": "^0.1.2" } }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, - "is-wsl": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz", - "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "dev": true }, "isarray": { @@ -3698,9 +3035,9 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3708,40 +3045,48 @@ } }, "js2xmlparser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.0.tgz", - "integrity": "sha512-WuNgdZOXVmBk5kUPMcTcVUpbGRzLfNkv7+7APq7WiDihpXVKrgxo6wwRpRl9OQeEBgKCVk9mR7RbzrnNWC8oBw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz", + "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==", "dev": true, "requires": { - "xmlcreate": "^2.0.0" + "xmlcreate": "^2.0.3" } }, "jsdoc": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.3.tgz", - "integrity": "sha512-Yf1ZKA3r9nvtMWHO1kEuMZTlHOF8uoQ0vyo5eH7SQy5YeIiHM+B0DgKnn+X6y6KDYZcF7G2SPkKF+JORCXWE/A==", + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.6.tgz", + "integrity": "sha512-znR99e1BHeyEkSvgDDpX0sTiTu+8aQyDl9DawrkOGZTTW8hv0deIFXx87114zJ7gRaDZKVQD/4tr1ifmJp9xhQ==", "dev": true, "requires": { - "@babel/parser": "^7.4.4", - "bluebird": "^3.5.4", + "@babel/parser": "^7.9.4", + "bluebird": "^3.7.2", "catharsis": "^0.8.11", "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.0", + "js2xmlparser": "^4.0.1", "klaw": "^3.0.0", - "markdown-it": "^8.4.2", - "markdown-it-anchor": "^5.0.2", - "marked": "^0.7.0", - "mkdirp": "^0.5.1", + "markdown-it": "^10.0.0", + "markdown-it-anchor": "^5.2.7", + "marked": "^0.8.2", + "mkdirp": "^1.0.4", "requizzle": "^0.2.3", - "strip-json-comments": "^3.0.1", + "strip-json-comments": "^3.1.0", "taffydb": "2.6.2", - "underscore": "~1.9.1" + "underscore": "~1.10.2" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } } }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", "dev": true }, "json-stable-stringify": { @@ -3765,10 +3110,19 @@ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, "klaw": { @@ -3791,31 +3145,46 @@ } }, "latest-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", "dev": true, "requires": { - "package-json": "^4.0.0" + "package-json": "^6.3.0" } }, - "lighthouse-logger": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.2.0.tgz", - "integrity": "sha512-wzUvdIeJZhRsG6gpZfmSCfysaxNEr43i+QT+Hie94wvHDKFLi4n7C2GqZ4sTC+PH5b5iktmXJvU87rWvhP3lHw==", - "dev": true, - "requires": { - "debug": "^2.6.8", - "marky": "^1.2.0" + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true + }, + "liftoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "dev": true, + "requires": { + "extend": "^3.0.0", + "findup-sync": "^2.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", "dev": true, "requires": { - "ms": "2.0.0" + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" } } } @@ -3847,19 +3216,6 @@ "resolve-pkg": "^2.0.0" } }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -3868,20 +3224,12 @@ "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, "lodash.memoize": { @@ -3891,65 +3239,12 @@ "dev": true }, "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "loglevel": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.6.tgz", - "integrity": "sha512-Sgr5lbboAUBo3eXCSPL4/KoVz3ROKquOjcctxmHIt+vol2DrqTQe3SwkKKuYhEiWB5kYa13YyopJ69deJ1irzQ==", - "dev": true - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "dev": true, "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" + "chalk": "^4.0.0" } }, "lowercase-keys": { @@ -3958,45 +3253,38 @@ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "dev": true }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { - "pify": "^3.0.0" + "semver": "^6.0.0" }, "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", @@ -4007,34 +3295,28 @@ } }, "markdown-it": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", - "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", "dev": true, "requires": { "argparse": "^1.0.7", - "entities": "~1.1.1", + "entities": "~2.0.0", "linkify-it": "^2.0.0", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" } }, "markdown-it-anchor": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz", - "integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", + "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", "dev": true }, "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", - "dev": true - }, - "marky": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.1.tgz", - "integrity": "sha512-md9k+Gxa3qLH6sUKpeC2CNkJK/Ld+bEz5X96nYwloqphQE0CKCVEKco/6jxEZixinqNdz5RFi/KaCyfbMDMAXQ==", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz", + "integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==", "dev": true }, "maxmin": { @@ -4047,6 +3329,33 @@ "figures": "^1.0.1", "gzip-size": "^3.0.0", "pretty-bytes": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } } }, "md5.js": { @@ -4066,32 +3375,6 @@ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", "dev": true }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -4121,8 +3404,28 @@ "requires": { "bn.js": "^4.0.0", "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -4145,28 +3448,16 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "minimist-options": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0" - }, - "dependencies": { - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - } - } + "mitt": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz", + "integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==", + "dev": true }, "mixin-deep": { "version": "1.3.2", @@ -4190,243 +3481,172 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true }, "mocha": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.2.tgz", - "integrity": "sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", + "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", "dev": true, "requires": { - "ansi-colors": "3.2.3", + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", + "chokidar": "3.4.3", + "debug": "4.2.0", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", + "ms": "2.1.2", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", + "which": "2.0.2", "wide-align": "1.1.3", - "yargs": "13.3.0", - "yargs-parser": "13.1.1", - "yargs-unparser": "1.6.0" + "workerpool": "6.0.2", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "2.0.0" }, "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, "requires": { - "ms": "^2.1.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fill-range": "^7.0.1" } }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" } }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "mocha-chrome": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/mocha-chrome/-/mocha-chrome-2.2.0.tgz", - "integrity": "sha512-RXP6Q2mlM2X+eO2Z8gribmiH4J9x5zu/JcTZ3deQSwiC5260BzizOc0eD1NWP3JuypGCKRwReicv4KCNIFtTZQ==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "chrome-launcher": "^0.11.2", - "chrome-remote-interface": "^0.28.0", - "chrome-unmirror": "^0.1.0", - "debug": "^4.1.1", - "deep-assign": "^3.0.0", - "import-local": "^2.0.0", - "loglevel": "^1.4.1", - "meow": "^5.0.0", - "nanobus": "^4.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "ms": "2.1.2" } }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" + "to-regex-range": "^5.0.1" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "optional": true }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "is-glob": "^4.0.1" } }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" + "binary-extensions": "^2.0.0" } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "is-extglob": "^2.1.1" } }, - "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "meow": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0", - "yargs-parser": "^10.0.0" + "p-locate": "^5.0.0" } }, "ms": { @@ -4435,142 +3655,88 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", "dev": true, "requires": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "p-limit": "^3.0.2" } }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" + "picomatch": "^2.2.1" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "is-number": "^7.0.0" } }, - "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", - "dev": true - }, - "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "isexe": "^2.0.0" } } } }, + "mocha-headless-chrome": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mocha-headless-chrome/-/mocha-headless-chrome-3.1.0.tgz", + "integrity": "sha512-qHz9D+Hzd8tDaNvPooUnvilWvAy1l+cJCBsV7dsme4wDKpvIaKRVGjU8RoirTfWQCkNOpjbweDpuNgo8wuOSHQ==", + "dev": true, + "requires": { + "args": "^5.0.1", + "mkdirp": "^1.0.4", + "puppeteer": "^4.0.0" + } + }, "module-deps": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.1.tgz", - "integrity": "sha512-UnEn6Ah36Tu4jFiBbJVUtt0h+iXqxpLqDvPS8nllbw5RZFmNJ1+Mz5BjYnM9ieH80zyxHkARGLnMIHlPK5bu6A==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz", + "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==", "dev": true, "requires": { "JSONStream": "^1.0.3", - "browser-resolve": "^1.7.0", + "browser-resolve": "^2.0.0", "cached-path-relative": "^1.0.2", "concat-stream": "~1.6.0", "defined": "^1.0.0", - "detective": "^5.0.2", + "detective": "^5.2.0", "duplexer2": "^0.1.2", "inherits": "^2.0.1", "parents": "^1.0.0", @@ -4580,60 +3746,14 @@ "subarg": "^1.0.0", "through2": "^2.0.0", "xtend": "^4.0.0" - }, - "dependencies": { - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, + "mri": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz", + "integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -4654,29 +3774,18 @@ } }, "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", "dev": true, "optional": true }, - "nanoassert": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz", - "integrity": "sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40=", + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", "dev": true }, - "nanobus": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/nanobus/-/nanobus-4.4.0.tgz", - "integrity": "sha512-Hv9USGyH8EsPy0o8pPWE7x3YRIfuZDgMBirzjU6XLebhiSK2g53JlfqgolD0c39ne6wXAfaBNcIAvYe22Bav+Q==", - "dev": true, - "requires": { - "nanoassert": "^1.1.0", - "nanotiming": "^7.2.0", - "remove-array-items": "^1.0.0" - } - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -4696,39 +3805,10 @@ "to-regex": "^3.0.1" } }, - "nanoscheduler": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/nanoscheduler/-/nanoscheduler-1.0.3.tgz", - "integrity": "sha512-jBbrF3qdU9321r8n9X7yu18DjP31Do2ItJm3mWrt90wJTrnDO+HXpoV7ftaUglAtjgj9s+OaCxGufbvx6pvbEQ==", - "dev": true, - "requires": { - "nanoassert": "^1.1.0" - } - }, - "nanotiming": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/nanotiming/-/nanotiming-7.3.1.tgz", - "integrity": "sha512-l3lC7v/PfOuRWQa8vV29Jo6TG10wHtnthLElFXs4Te4Aas57Fo4n1Q8LH9n+NDh9riOzTVvb2QNBhTS4JUKNjw==", - "dev": true, - "requires": { - "nanoassert": "^1.1.0", - "nanoscheduler": "^1.0.2" - } - }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, "nodemon": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.1.tgz", - "integrity": "sha512-UC6FVhNLXjbbV4UzaXA3wUdbEkUZzLGgMGzmxvWAex5nzib/jhcSHVFlQODdbuUHq8SnnZ4/EABBAbC3RplvPg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.6.tgz", + "integrity": "sha512-4I3YDSKXg6ltYpcnZeHompqac4E6JeAMpGm8tJnB9Y3T0ehasLa4139dJOcCrB93HHrUMsCrKtoAlXTqT5n4AQ==", "dev": true, "requires": { "chokidar": "^3.2.2", @@ -4739,8 +3819,8 @@ "semver": "^5.7.1", "supports-color": "^5.5.0", "touch": "^3.1.0", - "undefsafe": "^2.0.2", - "update-notifier": "^2.5.0" + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" }, "dependencies": { "anymatch": { @@ -4754,9 +3834,9 @@ } }, "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true }, "braces": { @@ -4769,19 +3849,28 @@ } }, "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.1", + "fsevents": "~2.1.2", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" + "readdirp": "~3.5.0" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" } }, "fill-range": { @@ -4793,15 +3882,28 @@ "to-regex-range": "^5.0.1" } }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -4811,12 +3913,27 @@ "binary-extensions": "^2.0.0" } }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -4824,12 +3941,12 @@ "dev": true }, "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, "requires": { - "picomatch": "^2.0.4" + "picomatch": "^2.2.1" } }, "supports-color": { @@ -4861,18 +3978,6 @@ "abbrev": "1" } }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -4882,14 +3987,11 @@ "remove-trailing-separator": "^1.0.1" } }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true }, "number-is-nan": { "version": "1.0.1", @@ -4934,18 +4036,6 @@ } } }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -4955,26 +4045,26 @@ "isobject": "^3.0.0" } }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" } }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" } }, "object.pick": { @@ -4995,12 +4085,40 @@ "wrappy": "1" } }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, "outpipe": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/outpipe/-/outpipe-1.1.1.tgz", @@ -5010,16 +4128,16 @@ "shell-quote": "^1.4.2" } }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "dev": true }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -5041,21 +4159,29 @@ "dev": true }, "package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", "dev": true, "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "dev": true }, "parents": { @@ -5068,28 +4194,35 @@ } }, "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", "dev": true, "requires": { - "asn1.js": "^4.0.0", + "asn1.js": "^5.2.0", "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", "evp_bytestokey": "^1.0.0", "pbkdf2": "^3.0.3", "safe-buffer": "^5.1.1" } }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" } }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -5109,13 +4242,10 @@ "dev": true }, "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true }, "path-is-absolute": { "version": "1.0.1", @@ -5123,18 +4253,6 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -5147,17 +4265,21 @@ "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", "dev": true }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "path-root-regex": "^0.1.0" } }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, "pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", @@ -5165,9 +4287,9 @@ "dev": true }, "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -5177,70 +4299,70 @@ "sha.js": "^2.4.8" } }, - "picomatch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", - "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "dev": true }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "dev": true, "requires": { - "pinkie": "^2.0.0" + "find-up": "^3.0.0" } }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", "dev": true, "requires": { - "find-up": "^3.0.0" + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" }, "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "lodash": "^4.17.14" } - } - } - }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "minimist": "^1.2.5" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -5251,9 +4373,9 @@ "dev": true }, "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true }, "pretty-bytes": { @@ -5272,21 +4394,27 @@ "dev": true }, "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true }, "pstree.remy": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", - "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, "public-encrypt": { @@ -5301,6 +4429,24 @@ "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, "punycode": { @@ -5309,6 +4455,63 @@ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "puppeteer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-4.0.1.tgz", + "integrity": "sha512-LIiSWTRqpTnnm3R2yAoMBx1inSeKwVZy66RFSkgSTDINzheJZPd5z5mMbPM0FkvwWAZ27a+69j5nZf+Fpyhn3Q==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "extract-zip": "^2.0.0", + "https-proxy-agent": "^4.0.0", + "mime": "^2.0.3", + "mitt": "^2.0.1", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^3.0.2", + "tar-fs": "^2.0.0", + "unbzip2-stream": "^1.3.3", + "ws": "^7.2.3" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "mime": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", + "dev": true + }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", @@ -5321,12 +4524,6 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, - "quick-lru": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", - "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", - "dev": true - }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -5354,6 +4551,14 @@ "requires": { "bytes": "1", "string_decoder": "0.10" + }, + "dependencies": { + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } } }, "rc": { @@ -5368,18 +4573,6 @@ "strip-json-comments": "~2.0.1" }, "dependencies": { - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -5397,39 +4590,36 @@ "readable-stream": "^2.0.2" } }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "inherits": "~2.0.3", "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "readdirp": { @@ -5443,14 +4633,13 @@ "readable-stream": "^2.0.2" } }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" + "resolve": "^1.1.6" } }, "regex-not": { @@ -5464,30 +4653,23 @@ } }, "registry-auth-token": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", - "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", "dev": true, "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" + "rc": "^1.2.8" } }, "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", "dev": true, "requires": { - "rc": "^1.0.1" + "rc": "^1.2.8" } }, - "remove-array-items": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/remove-array-items/-/remove-array-items-1.1.1.tgz", - "integrity": "sha512-MXW/jtHyl5F1PZI7NbpS8SOtympdLuF20aoWJT5lELR1p/HJDd5nqW8Eu9uLh/hCRY3FgvrIT5AwDCgBODklcA==", - "dev": true - }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -5506,15 +4688,6 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5527,6 +4700,12 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, "requizzle": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", @@ -5537,29 +4716,23 @@ } }, "resolve": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", - "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "requires": { + "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", "dev": true, "requires": { - "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - } + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" } }, "resolve-from": { @@ -5583,6 +4756,15 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -5590,9 +4772,9 @@ "dev": true }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -5609,9 +4791,9 @@ } }, "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "safe-json-parse": { @@ -5635,6 +4817,12 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=", + "dev": true + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -5642,12 +4830,29 @@ "dev": true }, "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", "dev": true, "requires": { - "semver": "^5.0.3" + "randombytes": "^2.1.0" } }, "set-blocking": { @@ -5708,21 +4913,6 @@ "fast-safe-stringify": "^2.0.7" } }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, "shell-quote": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", @@ -5730,15 +4920,15 @@ "dev": true }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, "simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "dev": true }, "snapdragon": { @@ -5757,15 +4947,6 @@ "use": "^3.1.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -5864,12 +5045,12 @@ "dev": true }, "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "dev": true, "requires": { - "atob": "^2.1.1", + "atob": "^2.1.2", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", @@ -5877,41 +5058,9 @@ } }, "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, "split-string": { @@ -5924,9 +5073,9 @@ } }, "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true }, "static-extend": { @@ -5971,36 +5120,27 @@ } }, "stream-http": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.1.0.tgz", - "integrity": "sha512-cuB6RgO7BqC4FBYzmnvhob5Do3wIdIsXAgGycHJnW+981gHqoYcYz9lqjJrk8WXRddbwPuqPYRl+bag6mYv4lw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.1.1.tgz", + "integrity": "sha512-S7OqaYu0EkFpgeGFb/NPOoPLxFko7TPqtEeFg5DXPB4v/KETHG0Ln6fRFrNezoelpaDKmycEmmZ81cC9DAwgYg==", "dev": true, "requires": { "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^3.0.6", - "xtend": "^4.0.0" + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" }, "dependencies": { "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } } } }, @@ -6047,32 +5187,15 @@ } } }, - "string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "safe-buffer": "~5.2.0" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -6082,34 +5205,10 @@ "ansi-regex": "^2.0.0" } }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "subarg": { @@ -6119,21 +5218,16 @@ "dev": true, "requires": { "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } }, "syntax-error": { "version": "1.4.0", @@ -6150,15 +5244,50 @@ "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", "dev": true }, - "term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, "requires": { - "execa": "^0.7.0" + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.4.tgz", + "integrity": "sha512-o3pS2zlG4gxr67GmFYBLlq+dM8gyRGUOvsrHclSkvtVtQbjV0s/+ZE8OpICbaj8clrX3tjeHngYGP7rweaBnuw==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } } }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -6173,52 +5302,8 @@ "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" - }, - "dependencies": { - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true - }, "timers-browserify": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", @@ -6243,9 +5328,9 @@ }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" @@ -6256,12 +5341,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true - }, - "qs": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz", - "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==", - "dev": true } } }, @@ -6285,6 +5364,12 @@ } } }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", @@ -6327,12 +5412,6 @@ } } }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, "tty-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", @@ -6345,12 +5424,27 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -6358,22 +5452,10 @@ "dev": true }, "uglify-js": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.2.tgz", - "integrity": "sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA==", - "dev": true, - "requires": { - "commander": "~2.20.3", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } + "version": "3.11.6", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.6.tgz", + "integrity": "sha512-oASI1FOJ7BBFkSCNDZ446EgkSuHkOZBuqRFrwXIKWCoXw8ZXQETooTQjkAcBS03Acab7ubCKsXnwuV2svy061g==", + "dev": true }, "umd": { "version": "3.0.3", @@ -6381,6 +5463,22 @@ "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", "dev": true }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, "undeclared-identifiers": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", @@ -6395,29 +5493,19 @@ } }, "undefsafe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", - "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", "dev": true, "requires": { "debug": "^2.2.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } } }, "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha1-BtzjSg5op7q8KbNluOdLiSUgOWE=" + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", + "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==", + "dev": true }, "underscore.string": { "version": "3.3.5", @@ -6429,6 +5517,15 @@ "util-deprecate": "^1.0.2" } }, + "union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dev": true, + "requires": { + "qs": "^6.4.0" + } + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -6442,12 +5539,12 @@ } }, "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "dev": true, "requires": { - "crypto-random-string": "^1.0.0" + "crypto-random-string": "^2.0.0" } }, "unset-value": { @@ -6490,12 +5587,6 @@ } } }, - "unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", - "dev": true - }, "upath": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", @@ -6503,56 +5594,34 @@ "dev": true }, "update-notifier": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", "dev": true, "requires": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } } } @@ -6587,13 +5656,19 @@ } } }, + "url-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", "dev": true, "requires": { - "prepend-http": "^1.0.1" + "prepend-http": "^2.0.0" } }, "use": { @@ -6625,14 +5700,13 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "v8flags": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", + "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "homedir-polyfill": "^1.0.1" } }, "vm-browserify": { @@ -6657,12 +5731,12 @@ } }, "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", + "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } @@ -6698,14 +5772,60 @@ } }, "widest-line": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", - "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dev": true, "requires": { - "string-width": "^2.1.1" + "string-width": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, + "workerpool": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "dev": true + }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", @@ -6732,6 +5852,21 @@ "color-convert": "^1.9.0" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -6761,41 +5896,32 @@ "dev": true }, "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, "ws": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.0.tgz", - "integrity": "sha1-Qi7ajAKktdundEumbuu9hLzvDsc=", - "requires": { - "async-limiter": "^1.0.0" - }, - "dependencies": { - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=" - } - } + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz", + "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==" }, "xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true }, "xmlcreate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.1.tgz", - "integrity": "sha512-MjGsXhKG8YjTKrDCXseFo3ClbMGvUD4en29H2Cev1dv4P/chlpw6KdYmlCWDkhosBVKRDjM836+3e3pm1cBNJA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", + "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==", "dev": true }, "xtend": { @@ -6810,16 +5936,10 @@ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", @@ -6831,7 +5951,7 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "yargs-parser": "^13.1.2" }, "dependencies": { "ansi-regex": { @@ -6840,15 +5960,6 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -6872,32 +5983,49 @@ } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" }, "dependencies": { "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true } } }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" } } } diff --git a/package.json b/package.json index 8dfc5378..73ad1c13 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "leapjs", - "version": "1.0.0", + "version": "1.1.0", "description": "JavaScript client for the Leap Motion Controller", "main": "lib", "engines": { @@ -15,14 +15,13 @@ }, "license": "Apache-2.0", "dependencies": { - "gl-matrix": "^3.1.0", - "underscore": "^1.4.4", - "ws": "^7.2.0" + "gl-matrix": "^3.3.0", + "ws": "^7.3.1" }, "devDependencies": { "browserify": "^16.5.0", "chai": "^4.2.0", - "grunt": "^1.0.4", + "grunt": "^1.3.0", "grunt-banner": "^0.6.0", "grunt-browserify": "^5.3.0", "grunt-contrib-clean": "^2.0.0", @@ -30,12 +29,12 @@ "grunt-contrib-watch": "^1.1.0", "grunt-exec": "^3.0.0", "grunt-string-replace": "^1.3.1", - "http-server": "*", - "jsdoc": "^3.6.3", + "http-server": "^0.12.3", + "jsdoc": "^3.6.6", "load-grunt-tasks": "^5.1.0", - "mocha": "^6.2.2", - "mocha-chrome": "^2.2.0", - "nodemon": "^2.0.1", - "uglify-js": "^3.7.2" + "mocha": "^8.2.1", + "mocha-headless-chrome": "^3.1.0", + "nodemon": "^2.0.6", + "uglify-js": "^3.11.5" } } diff --git a/test/assertUtil.js b/test/assertUtil.js index a39cc0bd..89be1c76 100644 --- a/test/assertUtil.js +++ b/test/assertUtil.js @@ -3,26 +3,20 @@ if (typeof module != 'undefined') { var assert = require('assert'); var util = require('util'); - var _ = require('underscore'); } else { var assert = window.assert; - var _ = window._; } function ok(test, message) { if (assert && assert.ok) { assert.ok(test, message); } else { - assert.equal(!!test, message); + assert.strictEqual(!!test, message); } } function isObject(o){ - if (_){ - return _.isObject(o); - } else { - return typeof o == 'object'; - } + return typeof o == 'object'; } var _DEFAULT_RANGE = 1e-6; @@ -62,7 +56,7 @@ */ validThreshold: function (threshold, comment) { if (!comment) comment = 'threshold violation'; - ok(!isNaN(threshold), "matrix3CloseTo: third argument must be a number"); + ok(!Number.isNaN(threshold), "matrix3CloseTo: third argument must be a number"); ok(threshold >= 0, 'matrix3CloseTo: threshold must be >= 0 -- is ' + threshold); }, @@ -90,9 +84,9 @@ if (_DEBUG) console.log('veca: %s', f(vecA)); if (!threshold) threshold = lib.DEFAULT_RANGE(); - _.each(_.range(0, 3), function (dim) { + for (let dim = 0; dim < 3; dim++){ lib.closeTo(vecA[dim], vecB[dim], threshold, comment, dim); - }); + } } catch (e) { console.log('vct error: %s', e, f(vecA), f(vecB)); throw e; @@ -115,7 +109,7 @@ if (!comment) comment = 'matrix3CloseTo'; lib.validThreshold(threshold, 'matrix3CloseTo: ' + comment); - if (!_.isNumber(threshold)) throw new Error("matrix3CloseTo: third argument must be a number"); + if (!(typeof threshold == 'number')) throw new Error("matrix3CloseTo: third argument must be a number"); if (threshold < 0) throw new Error('matrix3CloseTo: threshold must be >= 0 -- is ' + threshold); ok(matA && isObject(matA), f('vectorCloseTo bad argument 1: %s', matA)); @@ -123,17 +117,18 @@ if (!threshold) threshold = lib.DEFAULT_RANGE(); - _.each(_.range(0, 9), function (dim) { + for (let dim = 0; dim < 9; dim++){ lib.closeTo(matB[dim], matA[dim], threshold, dim + ': ' + comment, dim); - }); + } } catch (e) { console.log('mct error: %s -- %s, %s', e, f(matA), f(matB)); throw e; } }, closeTo: function (a, b, threshold, comment, dim) { - ok(!_.isNaN(a), 'bad number a: ' + comment); - ok(!_.isNaN(b), 'bad number b: ' + comment); + // Inline Definition of Number.IsNaN() + ok(!(typeof a === 'number' && a !== a), 'bad number a: ' + comment); + ok(!(typeof b === 'number' && b !== b), 'bad number b: ' + comment); var dd = Math.abs(a - b); if (_DEBUG) console.log('dim: %s, dd: %s, threshold: %s ', dim, dd, threshold); ok(dd <= threshold, comment); diff --git a/test/controller.js b/test/controller.js index f25a6697..1e9c465c 100644 --- a/test/controller.js +++ b/test/controller.js @@ -2,9 +2,9 @@ describe('Controller', function(){ describe('#new', function(){ it('should allow passing in options', function(done) { - var controller = fakeController({enableGestures:true}) + var controller = fakeController({"background":true}) controller.connection.send = function(message) { - if (message == '{"enableGestures":true}') { + if (message == '{"background":true}') { done(); } } @@ -65,29 +65,6 @@ describe('Controller', function(){ }) }) - describe('accumulating gestures', function() { - it('should accumulate gestures', function(done) { - var controller = fakeController({suppressAnimationLoop: true, frameEventName: 'animationFrame'}) - var count = 0 - controller.on('animationFrame', function(frame) { - assert.equal(7, frame.gestures.length); - controller.disconnect(); - done(); - }); - - controller.on('ready', function() { - controller.connection.handleData(JSON.stringify(fakeFrame({gestures:[fakeGesture()]}))); - controller.connection.handleData(JSON.stringify(fakeFrame({gestures:[fakeGesture(), fakeGesture()]}))); - controller.connection.handleData(JSON.stringify(fakeFrame({gestures:[fakeGesture(), fakeGesture(), fakeGesture(), fakeGesture()]}))); - - setTimeout(function() { - controller.emit('animationFrame', controller.lastConnectionFrame) - }, 50) - }); - controller.connect() - }); - }); - describe('frame events', function(){ it('should fire hand events for frames', function(done){ this.timeout(500); diff --git a/test/frame.js b/test/frame.js index 322b65f6..34d7bfd2 100644 --- a/test/frame.js +++ b/test/frame.js @@ -87,18 +87,17 @@ describe('Frame', function(){ }) describe('Invalid', function() { - it('should be invalid', function() { assert(!Leap.Frame.Invalid.valid)}) - it('should have empty fingers', function() { assert.equal(0, Leap.Frame.Invalid.fingers.length)}) - it('should have empty tools', function() { assert.equal(0, Leap.Frame.Invalid.tools.length)}) - it('should have empty pointables', function() { assert.equal(0, Leap.Frame.Invalid.pointables.length)}) - it('should return an invalid #pointable', function() { assert(!Leap.Frame.Invalid.pointable().valid)}) - it('should return an invalid #finger', function() { assert(!Leap.Frame.Invalid.finger().valid)}) - it('should return 0.0 from #rotationAngle', function() { assert.equal(0.0, Leap.Frame.Invalid.rotationAngle())}) + it('should be invalid', function() { assert(!Leap.Frame.Invalid.valid)}) + it('should have empty fingers', function() { assert.equal(0, Leap.Frame.Invalid.fingers.length)}) + it('should have empty pointables', function() { assert.equal(0, Leap.Frame.Invalid.pointables.length)}) + it('should return an invalid #pointable', function() { assert(!Leap.Frame.Invalid.pointable().valid)}) + it('should return an invalid #finger', function() { assert(!Leap.Frame.Invalid.finger().valid)}) + it('should return 0.0 from #rotationAngle', function() { assert.equal(0.0, Leap.Frame.Invalid.rotationAngle())}) it('should return an identity matrix from #rotationMatrix', function() { assertUtil.matrix3CloseTo(Leap.mat3.create(), Leap.Frame.Invalid.rotationMatrix(), assertUtil.DEFAULT_RANGE())}) - it('should return a null vector from #rotationAxis', function() { assertUtil.vectorCloseTo(Leap.vec3.create(),Leap.Frame.Invalid.rotationAxis(), assertUtil.DEFAULT_RANGE())}) - it('should return 1.0 from #scaleFactor', function() { assert.equal(1.0, Leap.Frame.Invalid.scaleFactor())}) - it('should return a null vector from #translation', function() { assertUtil.vectorCloseTo(Leap.vec3.create(),Leap.Frame.Invalid.translation(), assertUtil.DEFAULT_RANGE())}) - it('should return a null vector from #translation', function() { assert.equal(1.0, Leap.Frame.Invalid.scaleFactor())}) + it('should return a null vector from #rotationAxis', function() { assertUtil.vectorCloseTo (Leap.vec3.create(), Leap.Frame.Invalid.rotationAxis (), assertUtil.DEFAULT_RANGE())}) + it('should return 1.0 from #scaleFactor', function() { assert.equal(1.0, Leap.Frame.Invalid.scaleFactor())}) + it('should return a null vector from #translation', function() { assertUtil.vectorCloseTo(Leap.vec3.create(), Leap.Frame.Invalid.translation (), assertUtil.DEFAULT_RANGE())}) + it('should return a null vector from #translation', function() { assert.equal(1.0, Leap.Frame.Invalid.scaleFactor())}) }); describe('End to End', function(){ @@ -112,12 +111,15 @@ describe('Frame', function(){ assert.ok(frame.valid, 'frame is valid'); }); - _.each(frame.pointables, function (pointable) { + frame.pointables.forEach(function (pointable) { var stp = pointable.stabilizedTipPosition; - var match = _.find(frame.pointables, function (p) { - return p.stabilizedTipPosition[0] == stp[0] && - p.stabilizedTipPosition[0] == stp[0] && - p.stabilizedTipPosition[0] == stp[0]; + var match = undefined; + frame.pointables.forEach(function(p) { + if(p.stabilizedTipPosition[0] == stp[0] && + p.stabilizedTipPosition[1] == stp[1] && + p.stabilizedTipPosition[2] == stp[2]){ + match = p; + } }); assert.ok(match, 'found a match for stp ' + stp.join(',')); diff --git a/test/gestures.js b/test/gestures.js deleted file mode 100644 index fba92b16..00000000 --- a/test/gestures.js +++ /dev/null @@ -1,41 +0,0 @@ -describe('Gestures', function(){ - it("should allow single callback creation", function(done) { - var controller = fakeController({enableGestures:true}); - controller.gesture('keyTap', function() { - assert(this.frames[0]) - controller.disconnect(); - done() - }) - controller.on('ready', function() { - controller.processFrame(fakeFrame({gestures:[fakeGesture({type:'keyTap', state:'stop'})]})) - }) - controller.connect(); - }) - - it("should allow multiple callback creation", function(done) { - var controller = fakeController({enableGestures:true}); - var states = []; - var swiper = controller.gesture('swipe') - .start(function() { - states.push("start"); - }) - .stop(function() { - assert.deepEqual(['start', 'update', 'update', 'update'], states); - controller.disconnect(); - done(); - }) - .update(function() { - states.push("update"); - }); - - controller.on('ready', function() { - controller.processFrame(fakeFrame({gestures:[fakeGesture({type:'swipe', state:'start'})]})) - controller.processFrame(fakeFrame({gestures:[fakeGesture({type:'swipe', state:'update'})]})) - controller.processFrame(fakeFrame({gestures:[fakeGesture({type:'swipe', state:'update'})]})) - controller.processFrame(fakeFrame({gestures:[fakeGesture({type:'swipe', state:'update'})]})) - controller.processFrame(fakeFrame({gestures:[fakeGesture({type:'swipe', state:'stop'})]})) - }) - - controller.connect(); - }) -}) diff --git a/test/hand.js b/test/hand.js index 232e9709..1c3e8e65 100644 --- a/test/hand.js +++ b/test/hand.js @@ -11,7 +11,6 @@ describe('Hand', function(){ it('should have palmNormal', function() { assert(hand.palmNormal) }) it('should have sphereCenter', function() { assert(hand.sphereCenter) }) it('should have 5 pointables', function() { assert.equal(5, hand.pointables.length) }) - it('should have 0 tools', function() { assert.equal(0, hand.tools.length) }) it('should have 5 fingers', function() { assert.equal(5, hand.fingers.length) }) it('should have timeVisible', function() { assert(hand.timeVisible) }) it('should have stabilizedPalmPosition', function() { assert(hand.stabilizedPalmPosition) }) @@ -98,7 +97,6 @@ describe('Hand', function(){ describe('Invalid', function() { it('should be invalid', function() { assert(!Leap.Hand.Invalid.valid)}) it('should have empty fingers', function() { assert.equal(0, Leap.Hand.Invalid.fingers.length)}) - it('should have empty tools', function() { assert.equal(0, Leap.Hand.Invalid.tools.length)}) it('should have empty pointables', function() { assert.equal(0, Leap.Hand.Invalid.pointables.length)}) it('should return an invalid #pointable', function() { assert(!Leap.Hand.Invalid.pointable().valid)}) it('should return an invalid #finger', function() { assert(!Leap.Hand.Invalid.finger().valid)}) diff --git a/test/helpers/browser.html b/test/helpers/browser.html index 2f71d45a..db99fe9e 100644 --- a/test/helpers/browser.html +++ b/test/helpers/browser.html @@ -1,43 +1,36 @@ + - + Mocha Tests +
- - - + - - @@ -47,18 +40,7 @@ - - \ No newline at end of file + diff --git a/test/helpers/common.js b/test/helpers/common.js index 9ec7df9a..bf3b1301 100644 --- a/test/helpers/common.js +++ b/test/helpers/common.js @@ -8,16 +8,13 @@ if (typeof(window) !== 'undefined') { var fingerId = 0 , handId = 0 - , frameId =0 - , lastGestureState = false; + , frameId =0; var fakeController = exports.fakeController = function(opts) { - opts = _.defaults(opts || {}, {frameEventName: "deviceFrame", version: 6}); + opts = Object.assign({frameEventName: "deviceFrame", version: 6}, opts || {}); var controller = new Leap.Controller(opts); var connection = controller.connection; - lastGestureState = opts.enableGestures; - connection.setupSocket = function() { setTimeout(function() { connection.handleOpen() }, 1) var socket = { @@ -48,51 +45,41 @@ var createFrame = exports.createFrame = function(data) { return Leap.JSONProtocol(5)(data); } +function times(n, callback) { + var returnArray = []; + for (var i = 0; i < n; i++) { + returnArray.push(callback(i)); + } + return returnArray; +} + var fakeFrame = exports.fakeFrame = function(opts) { if (opts === undefined) opts = {}; handId = 0 fingerId = 0 - var fingers = opts.pointableData || _(opts.fingers || 0).times(function(n) { return fakeFinger(n) }), - tools = opts.pointableData || _(opts.tools || 0).times(function(n) { return fakeTool(n) }); + var fingers = opts.pointableData || times((opts.fingers || 0), function(n) { return fakeFinger(n) }); var frame = { id: opts.id || ++frameId, valid: true, timestamp: frameId, fingers: fingers, - tools: tools, - pointables: fingers.concat(tools), - hands: opts.handData || _(opts.hands || 0).times(function() { return fakeHand() }), + pointables: fingers.slice(), + hands: opts.handData || times((opts.hands || 0), function() { return fakeHand() }), r: opts.rotation || [[0,1,2], [2,3,4], [2,3,4]], t: opts.translation || [1, 2, 3], interactionBox: {center: [1,2,3], size: [1,2,3]}, currentFrameRate: 10 }; for (var i = 0; i != frame.pointables.length; i++) { - (frame.pointables[i].tool ? frame.tools : frame.fingers).push(frame.pointables[i]); + (frame.fingers).push(frame.pointables[i]); } - if (opts.gestures) { - frame.gestures = opts.gestures; - } return frame; }; -var fakeGesture = exports.fakeGesture = function(opts) { - if (opts === undefined) opts = { - type:"circle", - center:[2,3,4], - normal:[5,6,7], - handIds: [0, 1], - pointableIds: [4,5,6], - progress: 10, - radius: 20 - }; - return opts; -}; - var fakeHand = exports.fakeHand = function(opts) { if (opts === undefined) opts = {}; handId++ @@ -112,13 +99,13 @@ var fakeHand = exports.fakeHand = function(opts) { grabStrength: 0.5, pinchStrength: 0.5, confidence: 0.74094, - fingers: _(opts.hands || 5).times(function() { return fakeFinger() }) + fingers: times((opts.hands || 5), function() { return fakeFinger() }) } } -var fakeTool = exports.fakeTool = function() { +var fakeFinger = exports.fakeFinger = function (type) { fingerId++ - return { + var finger = { id: fingerId - 1, handId: 0, length: 5, @@ -131,11 +118,7 @@ var fakeTool = exports.fakeTool = function() { touchZone: "none", touchDistance: 5, timeVisible: 10 - } -} - -var fakeFinger = exports.fakeFinger = function(type) { - var finger = fakeTool(); + }; finger.type = type; finger.carpPosition = [10.1, 10.1, 10.1]; finger.mcpPosition = [11, 11, 11]; @@ -218,7 +201,7 @@ var fakeFinger = exports.fakeFinger = function(type) { var fakeActualFrame = exports.fakeActualFrame = function(){ -// var frameDump = '{"currentFrameRate":110.046,"gestures":[],"hands":[{"confidence":0.789415,"direction":[0.158462,0.627121,-0.762633],"grabStrength":0,"id":410,"palmNormal":[0.116439,-0.778872,-0.61628],"palmPosition":[60.9126,76.8613,36.0687],"palmVelocity":[3.25498,-2.77319,3.25398],"pinchStrength":0,"r":[[0.113258,-0.577876,0.808227],[-0.0837691,0.805011,0.587315],[-0.990028,-0.134223,0.0427661]],"s":1.15718,"sphereCenter":[54.5696,91.5943,0.920909],"sphereRadius":68.9144,"stabilizedPalmPosition":[58.3818,81.7843,32.9256],"t":[57.5602,63.7134,52.0596],"timeVisible":56257.5,"type":"right"}],"id":197377,"interactionBox":{"center":[0,200,0],"size":[235.247,235.247,147.751]},"pointables":[{"dipPosition":[-11.5826,65.0593,14.9045],"direction":[-0.545695,0.302478,-0.781489],"extended":true,"handId":410,"id":4100,"length":51.57,"mcpPosition":[28.3806,43.8226,70.3412],"pipPosition":[5.64499,55.5101,39.5761],"stabilizedTipPosition":[-22.9433,71.2217,-1.08015],"timeVisible":56257.5,"tipPosition":[-22.0341,71.31,-0.960369],"tipVelocity":[5.04347,3.46689,1.45025],"tool":false,"touchDistance":-0.177438,"touchZone":"touching","type":0,"width":18.75},{"dipPosition":[48.808,97.8943,-42.5311],"direction":[0.189785,-0.136463,-0.972296],"extended":true,"handId":410,"id":4101,"length":63.65,"mcpPosition":[38.0774,87.8413,21.1445],"pipPosition":[43.9495,101.388,-17.6403],"stabilizedTipPosition":[49.5451,90.7304,-59.3122],"timeVisible":56257.5,"tipPosition":[52.2109,88.0403,-56.3373],"tipVelocity":[9.16327,10.2824,4.49866],"tool":false,"touchDistance":0.209659,"touchZone":"hovering","type":1,"width":17.91},{"dipPosition":[82.27,98.519,-43.1687],"direction":[0.240974,-0.22168,-0.944875],"extended":true,"handId":410,"id":4102,"length":66.045,"mcpPosition":[62.4541,91.6378,22.3131],"pipPosition":[75.9251,104.356,-18.2901],"stabilizedTipPosition":[82.458,91.7338,-59.7407],"timeVisible":56257.5,"tipPosition":[84.3069,86.8553,-55.9189],"tipVelocity":[1.8102,-25.5031,14.1264],"tool":false,"touchDistance":0.210768,"touchZone":"hovering","type":2,"width":17.59},{"dipPosition":[104.219,100.709,-31.6167],"direction":[0.287859,-0.0803306,-0.954298],"extended":true,"handId":410,"id":4104,"length":63.635,"mcpPosition":[82.2655,89.5215,29.2434],"pipPosition":[96.8355,102.77,-7.13894],"stabilizedTipPosition":[104.576,92.5282,-48.7994],"timeVisible":56257.5,"tipPosition":[107.239,92.6262,-46.6113],"tipVelocity":[12.115,-4.25882,7.09828],"tool":false,"touchDistance":0.167466,"touchZone":"hovering","type":3,"width":16.738},{"dipPosition":[126.282,87.2965,-5.24043],"direction":[0.464892,-0.0265298,-0.88497],"extended":true,"handId":410,"id":4103,"length":50.07,"mcpPosition":[99.059,79.3988,35.2855],"pipPosition":[117.863,87.7769,10.7864],"stabilizedTipPosition":[129.399,82.0949,-21.6027],"timeVisible":56257.5,"tipPosition":[130.909,82.3187,-19.6813],"tipVelocity":[12.3715,7.4338,7.42059],"tool":false,"touchDistance":-0.0523789,"touchZone":"touching","type":4,"width":14.868}],"r":[[0.113258,-0.577876,0.808227],[-0.0837691,0.805011,0.587315],[-0.990028,-0.134223,0.0427661]],"s":1.15718,"t":[57.5602,63.7134,52.0596],"timestamp":56257460689}'; - var frameDump = '{ "currentFrameRate": 110.747, "gestures": [], "hands": [ { "confidence": 1, "direction": [ 0.490721, 0.425143, -0.760557 ], "grabStrength": 0, "id": 1, "palmNormal": [ 0.141838, -0.900216, -0.411695 ], "palmPosition": [ 47.033, 113.621, 102.153 ], "palmVelocity": [ -3.30303, 5.60355, 1.47788 ], "palmWidth": 92.4988, "pinchStrength": 0, "r": [ [ 0.584034, 0.313747, -0.748643 ], [ 0.0202196, 0.916373, 0.399814 ], [ 0.811477, -0.248642, 0.528849 ] ], "s": 1.42457, "sphereCenter": [ 64.9106, 183.062, 85.421 ], "sphereRadius": 81.7923, "stabilizedPalmPosition": [ 43.7677, 112.357, 87.4045 ], "t": [ 47.0678, 113.56, 102.138 ], "timeVisible": 810.321, "type": "right" } ], "id": 13319, "interactionBox": { "center": [ 0, 200, 0 ], "size": [ 235.247, 235.247, 147.751 ] }, "pointables": [ { "bases": [ [ [ 0.314831, 0.85025, 0.421848 ], [ -0.94682, 0.312444, 0.0768821 ], [ -0.0664349, -0.423619, 0.903401 ] ], [ [ 0.321292, 0.905114, 0.278459 ], [ -0.916178, 0.222714, 0.333191 ], [ 0.239559, -0.362169, 0.900802 ] ], [ [ 0.321292, 0.905114, 0.278459 ], [ -0.842096, 0.138569, 0.521222 ], [ 0.43318, -0.401954, 0.806715 ] ], [ [ 0.321292, 0.905114, 0.278459 ], [ -0.727658, 0.0477828, 0.684274 ], [ 0.606041, -0.422475, 0.673966 ] ] ], "btipPosition": [ -40.5204, 127.235, 43.4704 ], "carpPosition": [ 1.06923, 84.8729, 133.178 ], "dipPosition": [ -26.1017, 117.183, 59.5051 ], "direction": [ -0.43318, 0.401954, -0.806715 ], "extended": true, "handId": 1, "id": 10, "length": 52.9806, "mcpPosition": [ 1.06923, 84.8729, 133.178 ], "pipPosition": [ -11.0873, 103.251, 87.4667 ], "stabilizedTipPosition": [ -42.7656, 121.635, 37.8675 ], "timeVisible": 810.321, "tipPosition": [ -37.2041, 124.923, 47.1584 ], "tipVelocity": [ -4.03195, 5.29145, 3.86774 ], "tool": false, "touchDistance": 0.332609, "touchZone": "hovering", "type": 0, "width": 20.5858 }, { "bases": [ [ [ 0.929883, -0.0214331, 0.36723 ], [ -0.0899203, 0.954772, 0.283416 ], [ -0.356696, -0.296565, 0.885899 ] ], [ [ 0.906197, -0.0396238, 0.420996 ], [ -0.207543, 0.825755, 0.524457 ], [ -0.368421, -0.562636, 0.740073 ] ], [ [ 0.906197, -0.0396238, 0.420996 ], [ -0.0713341, 0.967006, 0.244561 ], [ -0.416796, -0.251652, 0.873471 ] ], [ [ 0.906197, -0.0396238, 0.420996 ], [ 0.0732099, 0.995267, -0.063911 ], [ -0.416471, 0.088737, 0.904808 ] ] ], "btipPosition": [ 70.8792, 158.015, 1.44856 ], "carpPosition": [ 10.6366, 106.62, 137.205 ], "dipPosition": [ 63.6455, 159.556, 17.1641 ], "direction": [ 0.416796, 0.251652, -0.873471 ], "extended": true, "handId": 1, "id": 11, "length": 59.7826, "mcpPosition": [ 37.3137, 128.8, 70.9488 ], "pipPosition": [ 53.4044, 153.373, 38.6263 ], "stabilizedTipPosition": [ 65.6654, 153.213, -14.0434 ], "timeVisible": 810.321, "tipPosition": [ 69.2154, 158.369, 5.06314 ], "tipVelocity": [ -4.20065, 9.68335, 2.59506 ], "tool": false, "touchDistance": 0.3253, "touchZone": "hovering", "type": 1, "width": 19.6635 }, { "bases": [ [ [ 0.874756, -0.223752, 0.42981 ], [ 0.0607727, 0.93066, 0.360802 ], [ -0.480737, -0.289493, 0.827699 ] ], [ [ 0.784201, -0.268147, 0.559576 ], [ -0.109474, 0.82787, 0.550133 ], [ -0.610773, -0.492674, 0.619862 ] ], [ [ 0.784201, -0.268147, 0.559576 ], [ 0.0996896, 0.944536, 0.312912 ], [ -0.612446, -0.189602, 0.767438 ] ], [ [ 0.784201, -0.268147, 0.559576 ], [ 0.297525, 0.95387, 0.0401336 ], [ -0.544524, 0.135015, 0.827807 ] ] ], "btipPosition": [ 114.34, 155.759, 14.6355 ], "carpPosition": [ 22.2091, 108.184, 141.712 ], "dipPosition": [ 103.938, 158.338, 30.4496 ], "direction": [ 0.612446, 0.189602, -0.767438 ], "extended": true, "handId": 1, "id": 12, "length": 68.1175, "mcpPosition": [ 56.3054, 128.716, 83.0076 ], "pipPosition": [ 86.233, 152.857, 52.6346 ], "stabilizedTipPosition": [ 107.84, 151.212, 1.45647 ], "timeVisible": 810.321, "tipPosition": [ 111.947, 156.352, 18.2727 ], "tipVelocity": [ -4.66062, 9.58164, 2.1671 ], "tool": false, "touchDistance": 0.333287, "touchZone": "hovering", "type": 2, "width": 19.3122 }, { "bases": [ [ [ 0.78739, -0.333431, 0.518498 ], [ 0.107759, 0.902593, 0.416789 ], [ -0.606963, -0.272303, 0.746624 ] ], [ [ 0.767862, -0.341851, 0.54178 ], [ -0.0158866, 0.835297, 0.549569 ], [ -0.640418, -0.4306, 0.635962 ] ], [ [ 0.767862, -0.341851, 0.54178 ], [ 0.147855, 0.917457, 0.36934 ], [ -0.623319, -0.203498, 0.755024 ] ], [ [ 0.767862, -0.341851, 0.54178 ], [ 0.301831, 0.939024, 0.164719 ], [ -0.565054, 0.0370446, 0.824222 ] ] ], "btipPosition": [ 129.561, 148.422, 33.3462 ], "carpPosition": [ 33.5367, 106.497, 146.693 ], "dipPosition": [ 118.829, 149.125, 49.0013 ], "direction": [ 0.623319, 0.203498, -0.755024 ], "extended": true, "handId": 1, "id": 13, "length": 65.4968, "mcpPosition": [ 72.1873, 123.837, 99.1495 ], "pipPosition": [ 101.275, 143.395, 70.2638 ], "stabilizedTipPosition": [ 123.254, 144.207, 20.7744 ], "timeVisible": 810.321, "tipPosition": [ 127.093, 148.584, 36.9468 ], "tipVelocity": [ -5.69924, 8.89887, 2.42685 ], "tool": false, "touchDistance": 0.331146, "touchZone": "hovering", "type": 3, "width": 18.3768 }, { "bases": [ [ [ 0.683148, -0.507227, 0.525386 ], [ 0.174865, 0.812118, 0.556675 ], [ -0.709035, -0.288419, 0.643493 ] ], [ [ 0.513798, -0.557566, 0.652022 ], [ 0.044047, 0.776152, 0.629005 ], [ -0.85678, -0.294462, 0.423345 ] ], [ [ 0.513798, -0.557566, 0.652022 ], [ 0.251492, 0.824509, 0.506888 ], [ -0.820222, -0.0964597, 0.563855 ] ], [ [ 0.513798, -0.557566, 0.652022 ], [ 0.443777, 0.823161, 0.354214 ], [ -0.734217, 0.107357, 0.670373 ] ] ], "btipPosition": [ 145.6, 125.131, 75.3324 ], "carpPosition": [ 43.833, 97.5082, 151.439 ], "dipPosition": [ 132.734, 127.012, 87.079 ], "direction": [ 0.820222, 0.0964597, -0.563855 ], "extended": true, "handId": 1, "id": 14, "length": 51.3483, "mcpPosition": [ 85.6283, 114.51, 113.508 ], "pipPosition": [ 116.426, 125.094, 98.2902 ], "stabilizedTipPosition": [ 138.574, 119.388, 60.1701 ], "timeVisible": 810.321, "tipPosition": [ 142.641, 125.564, 78.0341 ], "tipVelocity": [ -5.60761, 10.7884, 0.949619 ], "tool": false, "touchDistance": 0.331132, "touchZone": "hovering", "type": 4, "width": 16.3237 } ], "r": [ [ 0.584034, 0.313747, -0.748643 ], [ 0.0202196, 0.916373, 0.399814 ], [ 0.811477, -0.248642, 0.528849 ] ], "s": 1.42457, "t": [ 47.0678, 113.56, 102.138 ], "timestamp": 810321011 }'; +// var frameDump = '{"currentFrameRate":110.046,"hands":[{"confidence":0.789415,"direction":[0.158462,0.627121,-0.762633],"grabStrength":0,"id":410,"palmNormal":[0.116439,-0.778872,-0.61628],"palmPosition":[60.9126,76.8613,36.0687],"palmVelocity":[3.25498,-2.77319,3.25398],"pinchStrength":0,"r":[[0.113258,-0.577876,0.808227],[-0.0837691,0.805011,0.587315],[-0.990028,-0.134223,0.0427661]],"s":1.15718,"sphereCenter":[54.5696,91.5943,0.920909],"sphereRadius":68.9144,"stabilizedPalmPosition":[58.3818,81.7843,32.9256],"t":[57.5602,63.7134,52.0596],"timeVisible":56257.5,"type":"right"}],"id":197377,"interactionBox":{"center":[0,200,0],"size":[235.247,235.247,147.751]},"pointables":[{"dipPosition":[-11.5826,65.0593,14.9045],"direction":[-0.545695,0.302478,-0.781489],"extended":true,"handId":410,"id":4100,"length":51.57,"mcpPosition":[28.3806,43.8226,70.3412],"pipPosition":[5.64499,55.5101,39.5761],"stabilizedTipPosition":[-22.9433,71.2217,-1.08015],"timeVisible":56257.5,"tipPosition":[-22.0341,71.31,-0.960369],"tipVelocity":[5.04347,3.46689,1.45025],"tool":false,"touchDistance":-0.177438,"touchZone":"touching","type":0,"width":18.75},{"dipPosition":[48.808,97.8943,-42.5311],"direction":[0.189785,-0.136463,-0.972296],"extended":true,"handId":410,"id":4101,"length":63.65,"mcpPosition":[38.0774,87.8413,21.1445],"pipPosition":[43.9495,101.388,-17.6403],"stabilizedTipPosition":[49.5451,90.7304,-59.3122],"timeVisible":56257.5,"tipPosition":[52.2109,88.0403,-56.3373],"tipVelocity":[9.16327,10.2824,4.49866],"tool":false,"touchDistance":0.209659,"touchZone":"hovering","type":1,"width":17.91},{"dipPosition":[82.27,98.519,-43.1687],"direction":[0.240974,-0.22168,-0.944875],"extended":true,"handId":410,"id":4102,"length":66.045,"mcpPosition":[62.4541,91.6378,22.3131],"pipPosition":[75.9251,104.356,-18.2901],"stabilizedTipPosition":[82.458,91.7338,-59.7407],"timeVisible":56257.5,"tipPosition":[84.3069,86.8553,-55.9189],"tipVelocity":[1.8102,-25.5031,14.1264],"tool":false,"touchDistance":0.210768,"touchZone":"hovering","type":2,"width":17.59},{"dipPosition":[104.219,100.709,-31.6167],"direction":[0.287859,-0.0803306,-0.954298],"extended":true,"handId":410,"id":4104,"length":63.635,"mcpPosition":[82.2655,89.5215,29.2434],"pipPosition":[96.8355,102.77,-7.13894],"stabilizedTipPosition":[104.576,92.5282,-48.7994],"timeVisible":56257.5,"tipPosition":[107.239,92.6262,-46.6113],"tipVelocity":[12.115,-4.25882,7.09828],"tool":false,"touchDistance":0.167466,"touchZone":"hovering","type":3,"width":16.738},{"dipPosition":[126.282,87.2965,-5.24043],"direction":[0.464892,-0.0265298,-0.88497],"extended":true,"handId":410,"id":4103,"length":50.07,"mcpPosition":[99.059,79.3988,35.2855],"pipPosition":[117.863,87.7769,10.7864],"stabilizedTipPosition":[129.399,82.0949,-21.6027],"timeVisible":56257.5,"tipPosition":[130.909,82.3187,-19.6813],"tipVelocity":[12.3715,7.4338,7.42059],"tool":false,"touchDistance":-0.0523789,"touchZone":"touching","type":4,"width":14.868}],"r":[[0.113258,-0.577876,0.808227],[-0.0837691,0.805011,0.587315],[-0.990028,-0.134223,0.0427661]],"s":1.15718,"t":[57.5602,63.7134,52.0596],"timestamp":56257460689}'; + var frameDump = '{ "currentFrameRate": 110.747, "hands": [ { "confidence": 1, "direction": [ 0.490721, 0.425143, -0.760557 ], "grabStrength": 0, "id": 1, "palmNormal": [ 0.141838, -0.900216, -0.411695 ], "palmPosition": [ 47.033, 113.621, 102.153 ], "palmVelocity": [ -3.30303, 5.60355, 1.47788 ], "palmWidth": 92.4988, "pinchStrength": 0, "r": [ [ 0.584034, 0.313747, -0.748643 ], [ 0.0202196, 0.916373, 0.399814 ], [ 0.811477, -0.248642, 0.528849 ] ], "s": 1.42457, "sphereCenter": [ 64.9106, 183.062, 85.421 ], "sphereRadius": 81.7923, "stabilizedPalmPosition": [ 43.7677, 112.357, 87.4045 ], "t": [ 47.0678, 113.56, 102.138 ], "timeVisible": 810.321, "type": "right" } ], "id": 13319, "interactionBox": { "center": [ 0, 200, 0 ], "size": [ 235.247, 235.247, 147.751 ] }, "pointables": [ { "bases": [ [ [ 0.314831, 0.85025, 0.421848 ], [ -0.94682, 0.312444, 0.0768821 ], [ -0.0664349, -0.423619, 0.903401 ] ], [ [ 0.321292, 0.905114, 0.278459 ], [ -0.916178, 0.222714, 0.333191 ], [ 0.239559, -0.362169, 0.900802 ] ], [ [ 0.321292, 0.905114, 0.278459 ], [ -0.842096, 0.138569, 0.521222 ], [ 0.43318, -0.401954, 0.806715 ] ], [ [ 0.321292, 0.905114, 0.278459 ], [ -0.727658, 0.0477828, 0.684274 ], [ 0.606041, -0.422475, 0.673966 ] ] ], "btipPosition": [ -40.5204, 127.235, 43.4704 ], "carpPosition": [ 1.06923, 84.8729, 133.178 ], "dipPosition": [ -26.1017, 117.183, 59.5051 ], "direction": [ -0.43318, 0.401954, -0.806715 ], "extended": true, "handId": 1, "id": 10, "length": 52.9806, "mcpPosition": [ 1.06923, 84.8729, 133.178 ], "pipPosition": [ -11.0873, 103.251, 87.4667 ], "stabilizedTipPosition": [ -42.7656, 121.635, 37.8675 ], "timeVisible": 810.321, "tipPosition": [ -37.2041, 124.923, 47.1584 ], "tipVelocity": [ -4.03195, 5.29145, 3.86774 ], "tool": false, "touchDistance": 0.332609, "touchZone": "hovering", "type": 0, "width": 20.5858 }, { "bases": [ [ [ 0.929883, -0.0214331, 0.36723 ], [ -0.0899203, 0.954772, 0.283416 ], [ -0.356696, -0.296565, 0.885899 ] ], [ [ 0.906197, -0.0396238, 0.420996 ], [ -0.207543, 0.825755, 0.524457 ], [ -0.368421, -0.562636, 0.740073 ] ], [ [ 0.906197, -0.0396238, 0.420996 ], [ -0.0713341, 0.967006, 0.244561 ], [ -0.416796, -0.251652, 0.873471 ] ], [ [ 0.906197, -0.0396238, 0.420996 ], [ 0.0732099, 0.995267, -0.063911 ], [ -0.416471, 0.088737, 0.904808 ] ] ], "btipPosition": [ 70.8792, 158.015, 1.44856 ], "carpPosition": [ 10.6366, 106.62, 137.205 ], "dipPosition": [ 63.6455, 159.556, 17.1641 ], "direction": [ 0.416796, 0.251652, -0.873471 ], "extended": true, "handId": 1, "id": 11, "length": 59.7826, "mcpPosition": [ 37.3137, 128.8, 70.9488 ], "pipPosition": [ 53.4044, 153.373, 38.6263 ], "stabilizedTipPosition": [ 65.6654, 153.213, -14.0434 ], "timeVisible": 810.321, "tipPosition": [ 69.2154, 158.369, 5.06314 ], "tipVelocity": [ -4.20065, 9.68335, 2.59506 ], "tool": false, "touchDistance": 0.3253, "touchZone": "hovering", "type": 1, "width": 19.6635 }, { "bases": [ [ [ 0.874756, -0.223752, 0.42981 ], [ 0.0607727, 0.93066, 0.360802 ], [ -0.480737, -0.289493, 0.827699 ] ], [ [ 0.784201, -0.268147, 0.559576 ], [ -0.109474, 0.82787, 0.550133 ], [ -0.610773, -0.492674, 0.619862 ] ], [ [ 0.784201, -0.268147, 0.559576 ], [ 0.0996896, 0.944536, 0.312912 ], [ -0.612446, -0.189602, 0.767438 ] ], [ [ 0.784201, -0.268147, 0.559576 ], [ 0.297525, 0.95387, 0.0401336 ], [ -0.544524, 0.135015, 0.827807 ] ] ], "btipPosition": [ 114.34, 155.759, 14.6355 ], "carpPosition": [ 22.2091, 108.184, 141.712 ], "dipPosition": [ 103.938, 158.338, 30.4496 ], "direction": [ 0.612446, 0.189602, -0.767438 ], "extended": true, "handId": 1, "id": 12, "length": 68.1175, "mcpPosition": [ 56.3054, 128.716, 83.0076 ], "pipPosition": [ 86.233, 152.857, 52.6346 ], "stabilizedTipPosition": [ 107.84, 151.212, 1.45647 ], "timeVisible": 810.321, "tipPosition": [ 111.947, 156.352, 18.2727 ], "tipVelocity": [ -4.66062, 9.58164, 2.1671 ], "tool": false, "touchDistance": 0.333287, "touchZone": "hovering", "type": 2, "width": 19.3122 }, { "bases": [ [ [ 0.78739, -0.333431, 0.518498 ], [ 0.107759, 0.902593, 0.416789 ], [ -0.606963, -0.272303, 0.746624 ] ], [ [ 0.767862, -0.341851, 0.54178 ], [ -0.0158866, 0.835297, 0.549569 ], [ -0.640418, -0.4306, 0.635962 ] ], [ [ 0.767862, -0.341851, 0.54178 ], [ 0.147855, 0.917457, 0.36934 ], [ -0.623319, -0.203498, 0.755024 ] ], [ [ 0.767862, -0.341851, 0.54178 ], [ 0.301831, 0.939024, 0.164719 ], [ -0.565054, 0.0370446, 0.824222 ] ] ], "btipPosition": [ 129.561, 148.422, 33.3462 ], "carpPosition": [ 33.5367, 106.497, 146.693 ], "dipPosition": [ 118.829, 149.125, 49.0013 ], "direction": [ 0.623319, 0.203498, -0.755024 ], "extended": true, "handId": 1, "id": 13, "length": 65.4968, "mcpPosition": [ 72.1873, 123.837, 99.1495 ], "pipPosition": [ 101.275, 143.395, 70.2638 ], "stabilizedTipPosition": [ 123.254, 144.207, 20.7744 ], "timeVisible": 810.321, "tipPosition": [ 127.093, 148.584, 36.9468 ], "tipVelocity": [ -5.69924, 8.89887, 2.42685 ], "tool": false, "touchDistance": 0.331146, "touchZone": "hovering", "type": 3, "width": 18.3768 }, { "bases": [ [ [ 0.683148, -0.507227, 0.525386 ], [ 0.174865, 0.812118, 0.556675 ], [ -0.709035, -0.288419, 0.643493 ] ], [ [ 0.513798, -0.557566, 0.652022 ], [ 0.044047, 0.776152, 0.629005 ], [ -0.85678, -0.294462, 0.423345 ] ], [ [ 0.513798, -0.557566, 0.652022 ], [ 0.251492, 0.824509, 0.506888 ], [ -0.820222, -0.0964597, 0.563855 ] ], [ [ 0.513798, -0.557566, 0.652022 ], [ 0.443777, 0.823161, 0.354214 ], [ -0.734217, 0.107357, 0.670373 ] ] ], "btipPosition": [ 145.6, 125.131, 75.3324 ], "carpPosition": [ 43.833, 97.5082, 151.439 ], "dipPosition": [ 132.734, 127.012, 87.079 ], "direction": [ 0.820222, 0.0964597, -0.563855 ], "extended": true, "handId": 1, "id": 14, "length": 51.3483, "mcpPosition": [ 85.6283, 114.51, 113.508 ], "pipPosition": [ 116.426, 125.094, 98.2902 ], "stabilizedTipPosition": [ 138.574, 119.388, 60.1701 ], "timeVisible": 810.321, "tipPosition": [ 142.641, 125.564, 78.0341 ], "tipVelocity": [ -5.60761, 10.7884, 0.949619 ], "tool": false, "touchDistance": 0.331132, "touchZone": "hovering", "type": 4, "width": 16.3237 } ], "r": [ [ 0.584034, 0.313747, -0.748643 ], [ 0.0202196, 0.916373, 0.399814 ], [ 0.811477, -0.248642, 0.528849 ] ], "s": 1.42457, "t": [ 47.0678, 113.56, 102.138 ], "timestamp": 810321011 }'; return new Leap.Frame(JSON.parse(frameDump)); } \ No newline at end of file diff --git a/test/helpers/node.js b/test/helpers/node.js index cf93e5d2..45eff6e3 100644 --- a/test/helpers/node.js +++ b/test/helpers/node.js @@ -1,5 +1,4 @@ assert = require('chai').assert; -_ = require("underscore"); Leap = require('../../lib'); @@ -11,6 +10,5 @@ fakeFrame = common.fakeFrame; fakeActualFrame = common.fakeActualFrame; fakeFinger = common.fakeFinger; fakeController = common.fakeController; -fakeGesture = common.fakeGesture; createFrame = common.createFrame; fakePluginFactory = common.fakePluginFactory; diff --git a/test/pointable.js b/test/pointable.js index 7d31d7e5..b838a296 100644 --- a/test/pointable.js +++ b/test/pointable.js @@ -1,6 +1,6 @@ describe('Pointable', function(){ describe("properties", function() { - var data = fakeFrame({tools: 5, hands:1}) + var data = fakeFrame({fingers: 5, hands:1}) var frame = createFrame(data); var pointable = frame.hands[0].pointables[0]; @@ -15,8 +15,8 @@ describe('Pointable', function(){ it('should have touchZone', function() { assert.property(pointable, 'touchZone') }) it('should have touchDistance', function() { assert.property(pointable, 'touchDistance') }) it('should have timeVisible', function() { assert.property(pointable, 'timeVisible') }) - it('should not have mcpPosition', function() { assert.notProperty(pointable, 'mcpPosition') }) - it('should match Pointable in #toString', function() { assert.match(pointable.toString(), /^Pointable/); }) + //it('should not have mcpPosition', function() { assert.notProperty(pointable, 'mcpPosition') }) + it('should match Pointable in #toString', function() { assert.match(pointable.toString(), /^Finger/); }) it('should respond to hand()', function() { assert.equal(pointable.hand(), frame.hands[0]) }) }); });